Python的`fromtimestamp`执行离散跳转

Ram*_*hum 7 python datetime calendar epoch

datetime.fromtimestamp用来将纪元时间转换成当地时间.我发现datetime.fromtimestamp在某个时间点发生了一小时的离散跳跃,我完全不知道为什么会这样做.

(我也正在使用time.mktime将日期时间对象转换为纪元时间,正如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
... 
Run Code Online (Sandbox Code Playgroud)

选择特定的纪元时间:

>>> x = datetime_to_epoch_time(datetime.datetime(2012, 3, 30, 3, 0))
Run Code Online (Sandbox Code Playgroud)

使用fromtimestamp以下方法将其转换为日期时间:

>>> datetime.datetime.fromtimestamp(x)
datetime.datetime(2012, 3, 30, 3, 0)
Run Code Online (Sandbox Code Playgroud)

我们得到凌晨3点的时间.

现在让我们将它之前的时间转换为正好一秒钟:

>>> datetime.datetime.fromtimestamp(x-1)
datetime.datetime(2012, 3, 30, 1, 59, 59) 
Run Code Online (Sandbox Code Playgroud)

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

发生了什么?我知道这样的事情发生在闰日周围,但是从3月30日开始是闰日?

我应该注意到,我只在Linux上而不是在Windows上发生过这种情况.我认为不同的Linux计算机(在不同的时区)有不同的时间点,fromtimestamp跳跃.

小智 9

fromtimestamp使用当前用户的"本地环境",由POSIX C库定义(参见模块的man (3) tzset文档time).

如果您真的想要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)
Run Code Online (Sandbox Code Playgroud)

PS您还可以将进程的区域设置设置为UTC(但这可能不适用于非POSIX OS):

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


Mal*_*Box 5

简单。3 月 30 日大概是您所在时区的夏令时转换。

所以那天,时间确实从1:59:59到了3:00:00