在pandas中,为什么tz_convert会将EST中使用的时区更改为LMT?

时间:2014-06-12 15:18:45

标签: python pandas timezone pytz

在下面的脚本中,为什么 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>

2 个答案:

答案 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将能够实现做出正确事情的时区而无需用户跳过pytzlocalize箍。