How do you convert a time.struct_time object into a datetime object?
如何将python time.struct_time对象转换为datetime.datetime对象?
我有一个提供第一个和第二个需要第二个的库。
使用time.mktime()将时间元组(在localtime中)转换为自epoch以来的秒数,然后使用datetime.fromtimestamp()获取datetime对象。
1 2 3 4
| from datetime import datetime
from time import mktime
dt = datetime.fromtimestamp(mktime(struct)) |
号
- @纳迪亚为什么?你的看起来更简单,需要的模块更少。
- 注意,这在1900年之前失败了。你们现代人永远不会记住这个限制!
- 这会丢失tm_isdst数据吗?我认为是这样的,即使struct.tm_isdst是1,生成的datetime对象在返回.dst()上的None的程度上仍然是幼稚的。
- 这通常有效。但是,如果时间元组超过mktime接受的值,例如值(1970、1、1、0、0、0、0、1、-1),它将失败。在分析返回这个元组的HTTP请求的日期头之后,我遇到了这个问题。
- 正如@naxa提示的那样,这将为您提供具有dst校正的日期时间,即使原始数据没有dst偏移。
- @richvdh:c标准规定mktime()应考虑tm_isdst,python time.mktime()在cpython上调用c mktime()函数。如果struct.tm_isdst是-1或给定平台上的mktime()忽略输入tm_isdst时,mktime()可能选择错误的本地时间(例如,在DST("后退")转换结束时)。此外,如果本地时区过去有不同的UTC偏移量,而c mktime()不使用可以提供旧的UTC偏移量值的历史TZ数据库,则mktime()也可能返回错误的(例如,以小时为单位)值。
- @NAXA:如果mktime()不忽略给定平台上的tm_isdst(它在我的平台上忽略),那么fromtimestamp()肯定会释放信息:返回的表示本地时间的naive datetime对象可能不明确(timestamp->local time是确定性的(如果忽略闰秒),但local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp()可能会选择错误的UT如果它不使用历史TZ数据库,则为C偏移。
- @J.F.Sebastian:我提到的具体问题是,夏季的非DST结构时间总是通过以下方法转换为DST日期时间:datetime.fromtimestamp(mktime((2015,6,1,0,0,0,0,0,0)))->datetime.datetime(2015, 6, 1, 1, 0)。这也许是你想要的,但它给我带来了麻烦。你说得对,关于mktime()的规范以及历史TZ数据的处理方式还有更多的问题。实际上,这一切都表明(如@lysdexia所指出的),日期时间转换是复杂的,您需要仔细考虑。
- @richvdh:不正确。我平台上的mktime()总是返回正确的结果(包括dst/non dst),如果输入时间结构不含糊(或不存在),也就是说,只有在dst转换期间(它忽略了输入tm_isdst(这就是为什么pytz.timezone.localize()方法有is_dst参数:允许消歧)或在正闰秒附近。插入。我在我的机器上得到了datetime(2015,6,1,0,0)(不是datetime(2015,6,1,1,0))(在我的本地时区当时没有DST转换)。
- @J.F.塞巴斯蒂安没有错。我没有说任何东西返回了错误的结果;只是有一个从非DST到DST修正时间的隐式转换。2015/06/01在我的时区也不是DST转换;它处于DST周期的中间,这就是datetime.fromtimestamp()将其转换为DST校正时间的原因。
- @richvdh:我可以用America/New_York时区复制1 AM结果。在该时区通过当天的tm_isdst=0(2015-06-01)是不正确的。如果您通过了该日期的预期1或-1(允许mktime()自己计算出正确的tm_isdst值),那么mktime()返回正确的时间戳。我错了:即使当时没有DST转换,如果输入错误,mktime()也可能返回错误的结果。在我的系统中,fromtimestamp()在那个日期工作正常。
- "overflowError:mktime参数超出范围"当我尝试在结构上调用mktime时
- @Mlissner 1900年之前的解决方案是什么?
这样地:
1 2 3
| >>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35) |
- 别忘了输入时间,日期时间
- @JHwist-有些事情是可以信任的,人们可以自己解决:)
- 在structtime前面*做什么?
- @Rodling的*和**语法允许您将listy或dicty类型的对象扩展到单独的参数中,这是我最喜欢的Python lovelyness之一。有关详细信息,请参阅docs.python.org/2/tutorial/…。
- @如果你已经得到一个time.struct_time对象,就不需要jhwist导入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"。
- 注意,这也不处理时区。
这不是你问题的直接答案(已经很好地回答了)。然而,有几次在基础上咬了我几口,我无法强调,你应该仔细观察一下你的时间结构对象提供了什么,而其他时间字段可能提供了什么。
假设您同时具有time.struct_time对象和其他一些日期/时间字符串,请比较这两个对象,确保不会丢失数据,也不会无意中创建幼稚的datetime对象(如果可以这样做的话)。
例如,优秀的feedParser模块将返回"published"字段,并可能在其"published"字段中返回time.struct_time对象:
1
| 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) |
现在请注意"已发布"字段实际获得的内容。
1
| Mon, 09 Sep 2013 19:57:42 -0400 |
。
靠着史泰曼的胡子!时区信息!
在这种情况下,懒汉可能希望使用优秀的dateutil模块来保留时区信息:
1 2 3 4 5 6 7
| 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() |
这给了我们:
1 2 3 4 5
| 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,可以在日期分析文档中进行检查,因此这是多余的。