为啥 pytz localize() 不生成一个 tzinfo 与本地化它的 tz 对象匹配的 datetime 对象?

Posted

技术标签:

【中文标题】为啥 pytz localize() 不生成一个 tzinfo 与本地化它的 tz 对象匹配的 datetime 对象?【英文标题】:Why doesn't pytz localize() produce a datetime object with tzinfo matching the tz object that localized it?为什么 pytz localize() 不生成一个 tzinfo 与本地化它的 tz 对象匹配的 datetime 对象? 【发布时间】:2014-08-13 02:47:42 【问题描述】:

有没有人可以帮助我了解这里发生了什么?

import pytz
from datetime import datetime
tz = pytz.timezone('Europe/Berlin')
print repr(tz)
# <DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>
dt = datetime(2011, 1, 3, 18, 40)
result = tz.localize(dt)
print repr(result.tzinfo)
# <DstTzInfo 'Europe/Berlin' CET+1:00:00 STD>
assert result.tzinfo == tz, "Why aren't these the same timezone?"

我的理解是,pytz 时区对象上的localize() 方法将采用一个简单的日期时间对象,并添加一个与执行本地化的时区对象匹配的tzinfo 属性。在这种情况下似乎没有发生这种情况。

显然,我对时区或 pytz 处理时区的方式有一些误解。谁能解释一下?

【问题讨论】:

【参考方案1】:

它们同一时区 - "Europe/Berlin"

当您打印它们时,输出包括在该特定时间点应用的缩写和偏移量。

如果你检查the tz data sources,你会看到:

# Zone  NAME            GMTOFF   RULES       FORMAT   [UNTIL]
Zone    Europe/Berlin   0:53:28  -           LMT      1893 Apr
                        1:00     C-Eur       CE%sT    1945 May 24 2:00
                        1:00     SovietZone  CE%sT    1946
                        1:00     Germany     CE%sT    1980
                        1:00     EU          CE%sT

所以看起来当时区没有本地化日期时间时,它只使用第一个条目。

看起来 pytz 并没有保留原始本地平均时间偏差的额外 28 秒 - 但这并不重要,除非您使用的是 1893 年 4 月之前在柏林的日期。

【讨论】:

感谢您的评论。在 CET/CEST 上取得好成绩。这对我来说是一个糟糕的复制粘贴(现在已编辑)。我曾尝试过夏令时日期和非夏令时日期。我尝试在 Python 3.4 下使用最新的 pytz 运行它,并得到了相同的结果。请参阅:gist.github.com/bjmc/59d8650ae3d2aebb7584 非常感谢您提供有关 tz 数据源的信息。这是否意味着 [现代] 本地化日期的 tzinfo 属性永远不会与 pytz 中的抽象时区对象相等? 一般来说,如果没有特定的日期和时间,我不会认为 tzinfo 与另一个 tzinfo 具有可比性。但是,如果您知道这两个对象都来自 pytz(或来自 tzlocal),则可以比较它们的 .zone 属性,其中仅包含区域标识符("Europe/Berlin")的字符串。 不确定这是一个答案。它只是重复这是一个问题。当您尝试替换 datetime 对象的 tzinfo 时也会出现问题。 @PeterBengtsson - 然后不要使用替换,使用localize。问题是要求理解它发生的为什么,所以这就是这个答案的措辞。 @MattJohnson 我现在明白了。诀窍是始终使用localize()。即使这意味着您必须首先将其转换为时区 naive 日期时间,以便您可以将其本地化。

以上是关于为啥 pytz localize() 不生成一个 tzinfo 与本地化它的 tz 对象匹配的 datetime 对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 tzinfo 会在 python 中打破创建纪元时间?

使用 pytz 进行日期时间时区转换

使用pytz的Datetime时区转换

pytz 等/GMT-5

pytz UTC 转换

.localize 和 tzinfo 之间的 Python 日期时间差异