我有dt = datetime(2013,9,1,11),我想获得这个datetime对象的Unix时间戳。

当我做(dt - datetime(1970,1,1)).total_seconds()时,我得到了时间戳1378033200。

当转换回使用datetime.fromtimestamp时,我得到了datetime。Datetime(2013, 9,1,6,0)。

时间不对。我错过了什么?


当前回答

如果你想将python datetime转换为seconds since epoch,你应该显式地做:

>>> import datetime
>>> datetime.datetime(2012, 04, 01, 0, 0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012, 04, 01, 0, 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1333238400.0

在Python 3.3+中,您可以使用timestamp()来代替:

>>> import datetime
>>> datetime.datetime(2012, 4, 1, 0, 0).timestamp()
1333234800.0

其他回答

如果你想将python datetime转换为seconds since epoch,你应该显式地做:

>>> import datetime
>>> datetime.datetime(2012, 04, 01, 0, 0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012, 04, 01, 0, 0) - datetime.datetime(1970, 1, 1)).total_seconds()
1333238400.0

在Python 3.3+中,您可以使用timestamp()来代替:

>>> import datetime
>>> datetime.datetime(2012, 4, 1, 0, 0).timestamp()
1333234800.0

你错过的是时区。

假设你距离UTC时间还有5个小时,所以2013-09-01T11:00:00 local时间和2013-09-01T06:00:00Z时间是相同的。

你需要阅读datetime文档的顶部,它解释了时区和“naive”和“aware”对象。

如果您最初的天真datetime是UTC,那么恢复它的方法是使用utcfromtimestamp而不是fromtimestamp。

另一方面,如果您最初的天真datetime是本地的,那么首先就不应该从中减去UTC时间戳;使用datetime.fromtimestamp(0)代替。

或者,如果您有一个可感知的datetime对象,则需要在两侧使用一个本地(可感知的)epoch,或者显式地与UTC进行转换。

如果你已经或可以升级到Python 3.3或更高版本,你可以通过使用时间戳方法来避免所有这些问题,而不是试图自己弄清楚如何做。即使你不知道,你也可以考虑借用它的源代码。

(如果你能等到Python 3.4, PEP 341看起来很可能会进入最终版本,这意味着J.F. Sebastian和我在评论中谈论的所有东西都可以用stdlib完成,并且在Unix和Windows上都可以以相同的方式工作。)

import time
from datetime import datetime
time.mktime(datetime.now().timetuple())

当转换为unix时间戳时,python基本上是假设UTC,但在转换回来时,它会给你一个转换为本地时区的日期。

请看这个问题/答案; 获取datetime.datetime.fromtimestamp()使用的时区

如果datetime对象表示UTC时间,则不要使用time。Mktime,因为它假设元组在您的本地时区。相反,使用calendar.timegm:

>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60