27

我正在尝试编写一对函数,dtut,它们在正常的 unix 时间(自 1970-01-01 00:00:00 UTC 以来的秒数)和 Python 日期时间对象之间来回转换。

如果dtut是正确的逆,那么这段代码将打印两次相同的时间戳:

import time, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.fromtimestamp(u)
def ut(d): return time.mktime(d.timetuple())

u = 1004260000
print u, "-->", ut(dt(u))

唉,第二个时间戳比第一个少 3600 秒(一个小时)。我认为这只发生在非常特殊的 unixtime 上,也许在夏令时跳过的那个小时内。但是有没有办法写出来dtut所以它们是彼此真正的倒数?

相关问题:制作 matplotlib 的 date2num 和 num2date 完美逆

4

1 回答 1

41

您是正确的,此行为与夏令时有关。避免这种情况的最简单方法是确保您使用没有夏令时的时区,UTC 在这里最有意义。

datetime.datetime.utcfromtimestamp()calendar.timegm()处理 UTC 时间,并且是精确的倒数。

import calendar, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.utcfromtimestamp(u)
def ut(d): return calendar.timegm(d.timetuple())

以下是文档中为什么datetime.datetime.fromtimestamp()夏令时存在问题的一些解释:

返回 POSIX 时间戳对应的本地日期和时间,如time.time(). 如果可选参数 tz 为 None 或未指定,则将时间戳转换为平台的本地日期和时间,并且返回的 datetime 对象是幼稚的。

这里重要的部分是你得到一个天真的datetime.datetime对象,这意味着对象的一部分没有时区(或夏令时)信息。这意味着datetime.datetime在使用 时,多个不同的时间戳可以映射到同一个对象fromtimestamp(),如果您碰巧选择了在夏令时回滚期间的时间:

>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)
于 2012-11-06T23:18:24.040 回答