由于某些我无法弄清楚的原因,从以下代码:
>>> from pytz import timezone
>>> timezone('America/Chicago')
我明白了:
<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD>
什么时候,我认为,我应该得到:
<DstTzInfo 'America/Chicago' LMT-1 day, 18:00:00 STD>
...因为我认为我的时区距离UTC不到6小时9分钟。
我看过了 的源代码 pytz
但我承认我还没弄清楚出了什么问题。
我已将其他值传递给了 timezone()
函数,它返回的值似乎是正确的。但出于某种原因,与我的时区相关的信息不正确。
最后,我旁边的立方体中的同事确认该函数在他的机器上返回正确的时区信息。
有谁知道为什么我的时区('America/Chicago'
)将在9分钟后关闭?我正在运行版本 2015.7
的 pytz
安装使用 pip
。谢谢!
除非您的本地时区具有固定的UTC偏移量,否则在没有提供特定日期/时间的情况下讨论其特定值是没有意义的。
如果您提供时间,例如当前时间,那么您将看到 pytz
产生预期的UTC偏移量:
>>> from datetime import datetime
>>> import pytz
>>> datetime.now(pytz.timezone('America/Chicago')).strftime('%Z%z')
'CST-0600'
看到
如果您没有提供具体的日期/时间 pytz
可以从给定时区的可用utc偏移集返回任意utc偏移量。最近 pytz
版本返回与最早时间(LMT作为规则)相对应的utc偏移量,但您不应该依赖它。您和您的朋友可能会使用不同的pytz版本来解释结果的差异。
仅仅因为我的好奇心并不完全令人满意,我最近又对这个问题进行了一些研究。
最初,似乎差异源于不同版本的 pytz
。但是,在降级我的版本之后 pytz
在我确认我的机器上有不同结果的版本中,我发现这不是问题的根源:即使使用相同版本的 pytz
我的机器似乎使用基于LMT的UTC偏移,而其他机器使用基于CDT或CST的一个。
根据我与@ J.F.Sebastian的对话,我认为唯一可能的另一种可能性是系统级差异。我挖了进去 pytz
源代码多了一点,发现文件在哪里 pytz
从中得到至少一些时区信息 /usr/share/zoneinfo/
。所以我查看了该文件 /usr/share/zoneinfo/America/Chicago
虽然它是一个二进制文件,但它的一部分是可读的。在文件的中间有一个时区列表: LMTCDTCSTESTCWTCPT
。如你看到的, LMT
是列表中的第一个名字,正如@ J.F.Sebastian建议的那样,taht似乎是那个 pytz
用于我原始问题中描述的情况。
这就是Ubuntu 15.10中列表的样子。但是,在早期版本的Ubuntu(例如,Trusty和Precise)中,我得到结果-600而不是-609结果,同样的列表是 CDTCSTESTCWTCPT
。
我承认这是来自盲目探索和半理解,但似乎这是我在机器上看到的差异的原因。至于为什么 zoneinfo
各个版本的文件不同,这些差异对Ubuntu意味着什么,我不知道,但我想我会为那些同样好奇的人分享我的发现,并可能从社区获得有见地的更正/补充信息。
根据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)
out: 2015-06-11 13:30:00-05:00
正如您所提到的,原始文件与pytz模块存在一些差异:(在我的情况下使用Central时间)
XXXX ...... LIB / python2.7 /站点包/ pytz / zoneinfo中/美/中环
In [66]: start = start.replace(tzinfo=central)
In [67]: start.isoformat()
Out[67]: '2018-02-26T00:00:00-05:51'
如果您使用操作系统的标准文件(我在mac,ubuntu和centos中测试过)
在/ usr / share / zoneinfo中/美/中环
mv xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central-bak
ln -s /usr/share/zoneinfo/US/Central xxxx...../lib/python2.7/site-packages/pytz/zoneinfo/US/Central
问题得到解决
In [7]: central = timezone('US/Central')
In [8]: central
Out[8]: <DstTzInfo 'US/Central' CST-1 day, 18:00:00 STD>
In [10]: start = start.replace(tzinfo=central)
In [11]: start.isoformat()
Out[11]: '2018-02-27T00:00:00-06:00'