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


288

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

我有一个提供第一个库的图书馆,一个提供第二个库的图书馆。

Answers:


384

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

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
请注意,这在1900年之前就失败了。您的现代人永远不会记住此限制!
mlissner

3
这会丢失tm_isdst数据吗?我是这么认为的,所产生的DateTime对象仍然幼稚的程度,返回None.dst()即使struct.tm_isdst1
n611x007 2014年

3
这通常会起作用。但是,如果时间元组超出mktime接受的值(例如,值(1970,1,1,0,0,0,0,1,-1)),它将失败。我在解析返回此元组的HTTP请求上的Date标头后遇到了此问题。
user3820547 2014年

3
@richvdh:C标准指定mktime()应考虑tm_isdst到这一点,Python 在CPython上time.mktime()调用C mktime()函数。mktime()可能选择了错误的本地时间当它是模糊的(例如,-的-DST结束时(“后退”)的过渡),如果struct.tm_isdst-1,或者如果mktime()给定的平台上忽略输入 tm_isdst。同样,如果本地时区过去具有不同的utc偏移,并且C mktime()不使用可以提供旧utc偏移值的历史tz数据库,那么mktime()也可能返回错误的值(例如,按小时计算)。
jfs 2015年

1
@naxa:如果在给定的平台上mktime()不忽略tm_isdst(它在我的平台上确实存在),则fromtimestamp()肯定会丢失信息:代表本地时间的返回的天真的 datetime对象可能是模棱两可的(时间戳->本地时间是确定性的(如果我们忽略leap秒),但是local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp()`可能选择了错误的UTC,如果它不使用历史TZ数据库所抵消。
JFS

123

像这样:

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

3
别忘了#import时间,datetime
jhwist

7
@jhwist-人们可以信赖的一些东西可以自己解决:)
orip

14
@rodling *and **语法可让您扩展列表式或字典式对象以分隔参数-这是我最喜欢的Python可爱代码之一。见docs.python.org/2/tutorial/...更多信息
OrganicPanda

10
只要记住,如果struct_time有一个leap秒,这会给您一个ValueError,例如:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario 2014年

7
@berdario:返回兼容的值datetimedatetime(*t[:5]+(min(t[5], 59),))例如accept "2015-06-30 16:59:60 PDT"
jfs 2015年

37

这不是您问题的直接答案(已经很好回答了)。但是,由于有几次时间在我的基础上咬了我一口,所以我不能过分强调,您应该仔细查看一下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

斯托曼的胡子!时区信息!

在这种情况下,懒惰的人可能想要使用出色的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

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


7
*_parsedfeedparsed中的所有字段都已标准化为UTC,可以在日期解析文档中进行检查,因此这是多余的。
itorres

1
@itorres:如果我理解的话,这个答案不是关于标准化UTC,而是关于将时区信息保留在一个datetime对象中,该对象在feedparser解析原始字符串日期时会丢失。
davidag,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.