Python pytz时区函数返回一个9分钟的时区

ele*_*han 19 python timezone pytz timezone-offset

由于某些我无法弄清楚的原因,从以下代码:

>>> from pytz import timezone
>>> timezone('America/Chicago')
Run Code Online (Sandbox Code Playgroud)

我明白了:

<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD>
Run Code Online (Sandbox Code Playgroud)

我想,我应该得到:

<DstTzInfo 'America/Chicago' LMT-1 day, 18:00:00 STD>
Run Code Online (Sandbox Code Playgroud)

...因为我认为我的时区距离UTC只有6小时9分钟.

我已经查看了源代码,pytz但我承认我还没有完全弄清楚出了什么问题.

我已将其他值传递给timezone()函数,它返回的值似乎是正确的.但由于某些原因,与我的时区相关的信息不正确.

最后,我旁边的立方体中的同事确认该函数在他的机器上返回正确的时区信息.

有谁知道为什么我的时区('America/Chicago')会在9分钟后关闭?我运行版本2015.7pytz安装使用pip.谢谢!

lea*_*day 15

根据Carl Meyer在Google网上论坛答案中的回答做出回答

造成这种差异的原因是,这不是将时区无关的日期时间对象转换为时区感知对象的正确方法.

解释是:

"pytz时区类不代表与UTC的单一偏移量,它代表一个地理区域,在历史过程中,它可能经历了几个不同的UTC偏移.给定区域的最旧偏移量,表示从时间之前的偏移量区域是标准化的(在19世纪后期,大多数地方)通常被称为"LMT"(本地平均时间),并且它经常偏离UTC一个奇数分钟."

(引自Google网上论坛中引用的答案)

基本上,你应该这样做:

from datetime import datetime
import pytz

my_datetime = datetime(2015, 6, 11, 13, 30)
my_tz = pytz.timezone('America/Chicago')    
good_dt = my_tz.localize(my_datetime)

print(good_dt)
Run Code Online (Sandbox Code Playgroud)

out: 2015-06-11 13:30:00-05:00

  • @jfs是的,是的,downvote不公平。无法删除它。这个答案实际上鼓励每个人都使用localize()方法,该方法的使用范围比now()大得多。没有此注释,首先想到的是使用datetime(...,tzinfo = pytz.timezone('America / Chicago')),这很危险,会导致使用本地平均时间。因此,我认为在首先搜索此类内容时,找到方法localize()很重要 (2认同)

jfs*_*jfs 11

除非您的本地时区具有固定的 UTC 偏移量,否则在不提供特定日期/时间的情况下谈论其特定值是毫无意义的。

如果您提供时间,例如当前时间,那么您将看到pytz产生预期的 UTC 偏移量:

>>> from datetime import datetime
>>> import pytz
>>> datetime.now(pytz.timezone('America/Chicago')).strftime('%Z%z')
'CST-0600'
Run Code Online (Sandbox Code Playgroud)

如果您不提供特定的日期/时间,则pytz可能会从给定时区的可用 utc 偏移集中返回任意 utc 偏移。最近的pytz版本返回对应于最早时间的 utc 偏移量(通常为 LMT),但您不应依赖它。您和您的朋友可能使用不同的 pytz 版本,这可以解释结果的差异。

  • 您答案中的代码确实有效。我的问题是,在我的机器上调用 `pytz.timezone('America/Chicago')` 总是返回 `&lt;DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD&gt;`,并且总是返回 `&lt;DstTzInfo “美国/芝加哥”LMT-1 天,18:00:00 STD&gt;` 在我测试过的其他机器上(即使使用相同版本的“pytz”),我最初的问题是询问造成差异的原因。从您的回答中我认为这是由版本差异引起的,但事实似乎并非如此。 (3认同)
  • 我理解这一切并且同意你的观点。我只是好奇你是否知道是什么可以解释相同版本的“pytz”的差异。显然,如果您不选择给定特定时间,pytz 不会随机选择偏移量,因为结果是一致的(即使选择方法可能会随版本而变化)。我想知道为什么它在不同的机器上选择不同的偏移量。 (2认同)

ele*_*han 7

只是因为我的好奇心并没有完全得到满足,我最近对这个问题进行了更多的挖掘。

最初,差异似乎源于不同版本的pytz. 然而,在将我的版本降级pytz到一个版本后,我确认我得到的结果与我的机器上的结果不同,我发现这不是问题的根源:即使pytz我的机器版本相同使用基于 LMT 的 UTC 偏移量,而其他机器使用基于 CDT 或 CST 的偏移量。

根据我与@JFSebastian 的对话,我认为唯一的另一种可能是系统级别的差异。我深入研究了pytz源代码,发现pytz从中获取至少部分时区信息的文件位于/usr/share/zoneinfo/. 所以我查看了这个文件/usr/share/zoneinfo/America/Chicago,虽然它是一个二进制文件,但它的一部分是可读的。文件中途有一个时区列表:LMTCDTCSTESTCWTCPT. 如您所见,LMT是列表中的第一个名称,正如@JFSebastian 所建议的那样,taht 似乎是pytz在我的原始问题中描述的情况下使用的名称。

这就是列表在 Ubuntu 15.10 中的样子。但是,在 Ubuntu 的早期版本(例如,Trusty 和 Precise)中,我得到的结果是 -600 而不是 -609 结果,相同的列表是CDTCSTESTCWTCPT.

我承认这是由于大量的盲目探索和半理解,但这似乎是我在不同机器上看到的差异的原因。至于为什么zoneinfo不同版本的文件不同,以及这些差异对 Ubuntu 意味着什么,我不知道,但我想我会与那些同样好奇的人分享我的发现,并有可能从社区获得有见地的更正/补充信息.