【问题标题】:Python's `fromtimestamp` does a discrete jumpPython 的 `fromtimestamp` 进行离散跳转
【发布时间】:2012-04-12 11:46:44
【问题描述】:

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

(我也在使用time.mktime 将日期时间对象转换为纪元时间,as suggested by 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 进行跳转。

【问题讨论】:

    标签: python datetime calendar epoch


    【解决方案1】:

    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)
    

    附:您还可以将进程的语言环境设置为 UTC(但这可能不适用于非 POSIX 操作系统):

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我明白了。所以fromtimestamp 知道我居住的时区,并且知道可以跳过哪些时间。但是datetime 对象不知道这种跳跃:如果我从凌晨 2 点的对象中减去凌晨 3 点的datetime 对象,我会得到一小时的timedelta,我应该得到零。
      • 那么,我如何让datetime 对象知道我的时区,并让它们使用精确 某个时区作为fromtimestamp,所以它们将完全同步?
      • @RamRachum 在构造时间戳时传递tzinfo 标志。 pytz 库可能对此有所帮助。
      • @Amber 但是我怎么知道pytz 库给我的时区与fromtimestamp 使用的时区完全相同?如果fromtimestamp使用的是我的电脑上已经存在的某个时区而没有安装pytz,我可以使用它吗?
      猜你喜欢
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 2020-12-26
      • 2021-03-05
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多