Python的`fromtimestamp`会进行离散跳跃

8
我正在使用datetime.fromtimestamp将时期时间转换为本地时间。我发现datetime.fromtimestamp在某个时间点上会出现一个小时的离散跳跃,我完全不知道为什么会这样。
(我还使用time.mktime将datetime对象转换为时期时间,如Raymond Hettinger建议。我不确定这是否与此问题相关,因此我只是提前说一下。)
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time, datetime
>>> def datetime_to_epoch_time(datetime_):
...     return time.mktime(datetime_.timetuple()) + datetime_.microsecond / 1e6
... 

选择特定的纪元时间:
>>> x = datetime_to_epoch_time(datetime.datetime(2012, 3, 30, 3, 0))

将其转换为日期时间使用fromtimestamp:
>>> datetime.datetime.fromtimestamp(x)
datetime.datetime(2012, 3, 30, 3, 0)

我们得到了凌晨3点的时间。
现在让我们将时间转换为恰好早于此一秒:
>>> datetime.datetime.fromtimestamp(x-1)
datetime.datetime(2012, 3, 30, 1, 59, 59) 

我们突然到了凌晨1:59!

发生了什么事?我知道类似的事情在闰年时会发生,但自从3月30日成为闰年后,这种情况就一直存在吗?

需要注意的是,我只在Linux系统上遇到过这种情况,而在Windows系统上没有。而且我认为不同时区的Linux电脑在fromtimestamp跳跃的时间点可能会有所不同。

2个回答

9

fromtimestamp 函数使用当前用户的“本地环境”,其定义由POSIX C库确定(参见man (3) tzsettime模块的文档)。

如果您确实想获取当前用户环境的本地时间的 pytz 表示,那么datetime-tz 包中有一个函数可以自动检测它。

然而,常识是始终使用 UTC,并避免所有 DST 问题(仅在最终显示时使用本地时区)。使用 datetime.fromtimestamp(x, tz=pytz.UTC),如果您没有安装 pytz,则可以使用以下方式:

>>> datetime.datetime.fromtimestamp(x)
datetime.datetime(2012, 3, 30, 3, 0)
>>> datetime.datetime.utcfromtimestamp(x)
datetime.datetime(2012, 3, 30, 0, 0)
>>> datetime.datetime.utcfromtimestamp(x-1)
datetime.datetime(2012, 3, 29, 23, 59, 59)

P.S. 您也可以将进程的区域设置为 UTC(但这可能在非 POSIX 操作系统上无法正常工作):

>>> import os,time
>>> os.environ["TZ"] = "UTC"
>>> time.tzset()
>>> datetime.datetime.fromtimestamp(x)
datetime.datetime(2012, 3, 30, 0, 0)

5

很简单。3月30日是您所在时区的夏令时切换日期。

因此,在那一天,时间确实从1:59:59变为了3:00:00。


我明白了。所以fromtimestamp知道我所在的时区,并且知道要跳过哪些小时。但是datetime对象并不知道这个跳跃:如果我将2点钟的datetime对象减去3点钟的datetime对象,我得到一个一小时的timedelta,而实际上应该是零。 - Ram Rachum
那么,我如何使datetime对象意识到我的时区,并使它们使用与fromtimestamp完全同步的确切时区? - Ram Rachum
@RamRachum 在构建时间戳时传递 tzinfo 标志。使用 pytz 库可能会有所帮助。 - Amber
@Amber但是我怎么知道pytz库给出的时区和fromtimestamp使用的时区完全相同?如果fromtimestamp正在使用计算机上已经存在而无需安装pytz的某个特定时区,那么我是否可以使用它? - Ram Rachum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接