带有 pytz 时区的日期时间。不同的偏移量取决于 tzinfo 的设置方式[重复]

Posted

技术标签:

【中文标题】带有 pytz 时区的日期时间。不同的偏移量取决于 tzinfo 的设置方式[重复]【英文标题】:datetime with pytz timezone. Different offset depending on how tzinfo is set [duplicate] 【发布时间】:2014-07-05 03:11:34 【问题描述】:

我今天遇到了一个有趣的情况。谁能解释为什么 ts1 和 ts2 的偏移量不同? ts1 是一个日期时间对象,可以立即识别时区。 ts2 是一个 datetime 对象,它从 timezone-naive 开始并替换了它的 tzinfo。但是,它们最终会得到不同的偏移量。

>>> from pytz import timezone
>>> EST = timezone('America/New_York')
>>> ts1 = datetime.datetime.now(tz=EST)
>>> ts2 = datetime.datetime.now()
>>> ts2 = ts2.replace(tzinfo=EST)
>>> print ts1
2014-05-16 11:25:16.749748-04:00
>>> print ts2
2014-05-16 11:25:19.581710-05:00

【问题讨论】:

【参考方案1】:

当您调用ts2.replace(tzinfo=EST) 时,您获得的tzinfo 对象与您通过ts1 获得的对象不匹配:

>>> ts1
datetime.datetime(2014, 5, 16, 11, 51, 7, 916090, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
>>> ts2
datetime.datetime(2014, 5, 16, 11, 51, 30, 922692, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)

你最终会选择 LMT 而不是 EDT。

pytz documentation 实际上指出,将pytz 与标准日期时间对象的tzinfo 参数一起使用根本不适用于许多时区:

不幸的是,使用标准日期时间的 tzinfo 参数 对于许多时区,构造函数“不起作用”。

&gt;&gt;&gt; datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt) '2002-10-27 12:00:00 LMT+0020'

不过,对于没有夏令时转换的时区来说是安全的, 比如UTC:

&gt;&gt;&gt; datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt) '2002-10-27 12:00:00 UTC+0000'

我不确定为什么第一个有效;可能是因为在最初使用 tzinfo 对象构造对象时,它实际上不需要转换任何内容。

编辑

啊,Python documentation 注意到将 datetime.datetime.now()tz arg 一起使用相当于:

EST.fromutc(datetime.utcnow().replace(tzinfo=EST))

这意味着您正在从 UTC 转换,pytz 是安全的。所以这就是第一个有效的原因。

【讨论】:

pytz 提供了.fromutc() 方法的自定义实现,该方法使用._utc_transition_times 列表来获取正确的tzinfo 对象。【参考方案2】:

根据documentation,将时区应用于天真的日期时间的正确方法是使用localize 方法。

ts1 = eastern.localize(datetime.datetime.now())

另外,我建议您使用避免 EST 作为变量名称,因为它通常是“东部标准时间”的标准,而 America/New_York 包含“东部标准时间”(EST)和“东部夏令时间”(美国东部时间)。

【讨论】:

在夏令时转换期间可能会返回不正确的结果,请改用datetime.now(eastern)

以上是关于带有 pytz 时区的日期时间。不同的偏移量取决于 tzinfo 的设置方式[重复]的主要内容,如果未能解决你的问题,请参考以下文章

pytz 时区的 STD 偏移量

如何使用 pytz 从时区字符串中获取 UTC 偏移量?

Python & pytz:确定时区是不是支持 DST 以及 DST 和非 DST UTC 偏移量是多少

来自 UTC 偏移的 Pytz 时区

Mongo ObjectID:即使使用 pytz,“也无法比较原始偏移量和可感知偏移量的日期时间”

没有时区偏移的 HTML 输入类型日期和时间