【问题标题】:How do you convert a time.struct_time object into a datetime object?如何将 time.struct_time 对象转换为 datetime 对象?
【发布时间】:2009-11-08 20:23:23
【问题描述】:

如何将 Python time.struct_time 对象转换为 datetime.datetime 对象?

我有一个提供第一个的库和一个需要第二个的库。

【问题讨论】:

    标签: python datetime


    【解决方案1】:

    使用time.mktime()将时间元组(本地时间)转换为纪元以来的秒数,然后使用datetime.fromtimestamp()获取日期时间对象。

    from datetime import datetime
    from time import mktime
    
    dt = datetime.fromtimestamp(mktime(struct))
    

    【讨论】:

    • 请注意,这在 1900 年之前就失败了。你们现代人永远不会记得这个限制!
    • 这会丢失tm_isdst 数据吗?我认为是这样,即使struct.tm_isdst1,生成的日期时间对象仍然很幼稚,以至于在.dst() 上返回None
    • 这通常会起作用。但是,如果时间元组超出 mktime 接受的值,例如值 (1970, 1, 1, 0, 0, 0, 0, 1, -1),它将失败。在解析返回此元组的 HTTP 请求上的 Date 标头后,我遇到了这个问题。
    • @richvdh:C 标准规定 mktime() 应考虑 tm_isdst,Python time.mktime() 在 CPython 上调用 C mktime() 函数。如果struct.tm_isdst-1 或者如果给定平台上的mktime() 忽略输入 tm_isdst。此外,如果本地时区过去有不同的 utc 偏移量,并且 C mktime() 不使用可以提供旧 utc 偏移量值的历史 tz 数据库,那么 mktime() 也可能返回错误(例如,按小时)值.
    • @naxa: 如果mktime() 不忽略给定平台上的tm_isdst(它在我的平台上),那么fromtimestamp() 肯定会丢失信息:返回的 naive datetime 表示本地时间的对象可能不明确(时间戳 -> 本地时间是确定性的(如果我们忽略闰秒)但 local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp()` 可能会选择错误的 UTC 偏移量,如果它不使用历史 tz数据库。
    【解决方案2】:

    像这样:

    >>> structTime = time.localtime()
    >>> datetime.datetime(*structTime[:6])
    datetime.datetime(2009, 11, 8, 20, 32, 35)
    

    【讨论】:

    • 别忘了#import time, datetime
    • @jhwist - 有些事情人们可以自己解决:)
    • @rodling *** 语法允许您将 listy 或 dicty 类型的对象扩展为单独的参数 - 这是我最喜欢的 Python 可爱部分之一。请参阅docs.python.org/2/tutorial/… 了解更多信息
    • 请记住,如果 struct_time 有闰秒,这会给你一个 ValueError,例如:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
    • @berdario:返回与datetime 兼容的值:datetime(*t[:5]+(min(t[5], 59),)) 例如,接受"2015-06-30 16:59:60 PDT"
    【解决方案3】:

    这不是您问题的直接答案(已经很好地回答了)。但是,我曾多次在基本面上咬过我,我怎么强调都不为过,你应该仔细看看你的 time.struct_time 对象提供了什么,以及其他时间字段可能有什么。

    假设您同时拥有 time.struct_time 对象和其他一些日期/时间字符串,请比较两者,并确保您没有丢失数据并无意中创建了一个幼稚的 datetime 对象,否则您可以这样做。

    例如,优秀的 feedparser 模块会返回一个“published”字段,并可能在其“published_pa​​rsed”字段中返回一个 time.struct_time 对象:

    time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)
    

    现在请注意您在“已发布”字段中实际得到的信息。

    Mon, 09 Sep 2013 19:57:42 -0400
    

    Stallman 的胡须!时区信息!

    在这种情况下,懒人可能想使用优秀的 dateutil 模块来保存时区信息:

    from dateutil import parser
    dt = parser.parse(entry["published"])
    print "published", entry["published"])
    print "dt", dt
    print "utcoffset", dt.utcoffset()
    print "tzinfo", dt.tzinfo
    print "dst", dt.dst()
    

    这给了我们:

    published Mon, 09 Sep 2013 19:57:42 -0400
    dt 2013-09-09 19:57:42-04:00
    utcoffset -1 day, 20:00:00
    tzinfo tzoffset(None, -14400)
    dst 0:00:00
    

    然后可以使用可识别时区的日期时间对象将所有时间标准化为 UTC 或您认为很棒的任何时间。

    【讨论】:

    • feedparsed 中的所有 *_parsed 字段都已标准化为 UTC,可以在 the date parsing documentation 中检查,因此这是多余的。
    • @itorres:如果我理解的话,这个答案不是关于标准化为 UTC,而是关于将时区信息保存在datetime 对象中,当feedparser 解析原始字符串日期时该对象会丢失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多