在下面的脚本中,为什么 tz 和 tz2 不同?
import pandas
import pytz
tz = pytz.timezone('US/Eastern')
t = pandas.Timestamp('2014-03-03 08:05:39.216809')
tz2 = t.tz_localize(pytz.UTC).tz_convert(tz).tz
在这种情况下, tz 显示为:
<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>
但 tz2 显示为:
<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>
大熊猫不应该尊重我传递给 tz_convert 的时区吗? (这可能是一个已知的错误吗?)
更新
这似乎是关于pytz的更多问题。仍然让我困惑的行为(但可能有一个明确的解释)是为什么跟随不同?
tz
<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>
tz.localize(t).tzinfo
<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>
答案 0 :(得分:6)
这些不一样。
pytz.timezone(...)
为您提供最新的时区! (截至你的pytz包裹日期)。
安装旧版pytz
In [47]: pytz.__version__
Out[47]: '2012j'
In [48]: pytz.timezone('US/Eastern')
Out[48]: <DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>
已安装最新版本
In [2]: pytz.__version__
Out[2]: '2014.4'
In [3]: pytz.timezone('US/Eastern')
Out[3]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>
Pandas正确处理这个问题,您可以像这样直接使用日期时间
pytz.timezone('US/Eastern').localize(datetime.datetime(2012,1,1))
最近,时区定义已更改为使用LMT(本地平均时间)。这与您在本地化使用日期时无关紧要,因为它们将在正确的时区内。
因此,在回答您的问题时,tz2
是正确的,因为它本地化为其日期正确的时区,而tz
对于当前日期是“正确的”。
答案 1 :(得分:3)
这是pytz
的解决方法,因为datetime.tzinfo
,即表示时区对象和datetime.datetime
对象之间接口的抽象类,预计能够发现只有当地时间的 偏移时区,这通常不可能,因为由于夏令时或其他政府行为导致的偏移变化,某些本地时间不明确。
localize
的目的是获取本地时间和其他is_dst
参数,并返回一个明确的datetime.datetime
,其中包含一个定制的时区对象给出那个时间的正确偏移量。但pytz
时区不是本地化时间的结果,知道它不能总是给出正确的偏移,所以它不会非常努力 - 相反,它只是默认为Zoneinfo数据库中第一个条目。在US/Eastern
的情况下,这只是纽约当地的平均时间(因此那些疯狂的四分钟)。您可以通过尽早本地化来获得相同的偏移量:
In [28]: pytz.timezone('US/Eastern').localize(datetime.datetime(1901, 1, 1))
Out[28]: datetime.datetime(1901, 1, 1, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)
我不知道为什么pytz
版本2012j表现出不同的行为,但我猜想在过去的两年中,历史条目都被添加到Zoneinfo,或者在那个时期的某个时刻未加入本地化{{ 1}}时区从Zoneinfo中的正确偏移(有时是错误的)猜测切换到Zoneinfo中的(明显错误的)最旧偏移。
完成PEP 431后,pytz
方法会在适当的时候采用datetime.tzinfo
个参数,而is_dst
将能够实现做出正确事情的时区而无需用户跳过pytz
和localize
箍。