在熊猫中从天真的本地夏令时转换为天真的本地标准时间

Posted

技术标签:

【中文标题】在熊猫中从天真的本地夏令时转换为天真的本地标准时间【英文标题】:Convert from naive local daylight time to naive local standard time in pandas 【发布时间】:2020-01-03 00:07:21 【问题描述】:

我有按当地夏令时记录的每小时数据记录(对我来说,这是美国/太平洋时间)。这些将通过 csv 读取。当我们向前跳时,在 DST 开始时 02:00 存在一个间隙。在秋季,我相信在太平洋夏令时间 01:00 收集的数据被标记为 01:00,下一小时被标记为 02:00(假设 PST)。

我想翻译时间戳,以便它们与存储在 PST 中的其他数据很好地配合使用。下面是我的尝试,我只关注应该简化讨论的索引。

tndx = pd.DatetimeIndex(["2016-11-06 00:00",""2016-11-06 01:00","2016-11-06 02:00","2016-11-06 03:00"])
tndx.tz_localize('US/Pacific',ambiguous="NaT").tz_convert('Etc/GMT+8') 
print(tndx).tz_localize(None)

输出是:

DatetimeIndex(['2016-11-05 23:00:00-08:00',                       'NaT',
               '2016-11-06 02:00:00-08:00', '2016-11-06 03:00:00-08:00']

这有两个问题。首先,从 PST 的角度来看,我现在似乎错过了 00:00 和 01:00 的两个时间戳。我知道该过程是有损的,但我不认为该过程必须有损超过一个时间戳。 ambiguous = "infer" 出现异常,因为没有多余的值。当我按照 karajdaar 的建议将其显式设置为布尔数组时,我不会丢失额外的时间点。然而,布尔列表并不是那么容易获得——我不能使用 tndx 因为它还不知道 tz。我能想到的唯一方法是这条通过 datetime.dst 的迂回路线,涉及单独的 DataFrame 和转换:

# Create a date range that spans the possible times and is hourly
ndx2 = pd.date_range(start=pd.Timestamp(2016,11,5), end =pd.Timestamp(2016,11,7),freq='H',tz='US/Pacific')

# Here is the determination of whether it is dst
isdst = [bool(x.dst()) for x in ndx2.to_pydatetime()]

# I use DataFrame indexing to perform the lookup 
# for values in my original index
df2 = pd.DataFrame("isdst":isdst,index=ndx2.tz_localize(None))
df2 = df2.loc[~df2.index.duplicated(keep="last")]
ambig = df2[tndx]    # This is what I would use for ambiguous

其次,我使用 Etc/GMT+8 是因为我发现它提供了正确的偏移量和时间戳,特别是在我再次使邮票变得幼稚之后。如果我不剥离时区信息(即没有最后一个tz_convert(None)),输出将是:

>>> tndx.tz_localize('US/Pacific',ambiguous='NaT').tz_convert('Etc/GMT+8')
DatetimeIndex(['2016-11-05 23:00:00-08:00',                       'NaT',
               '2016-11-06 02:00:00-08:00', '2016-11-06 03:00:00-08:00'],
              dtype='datetime64[ns, Etc/GMT+8]', freq=None)

这种情况下的偏移量看起来不错,但 dtype 中的时区似乎具有误导性,无论如何,为什么名为 GMT+8 的时区给出的偏移量为 -8?我对这些转换有什么不明白的地方?

【问题讨论】:

【参考方案1】:

这种情况下的偏移量看起来不错,但 dtype 中的时区似乎具有误导性,无论如何,为什么名为 GMT+8 的时区给出的偏移量为 -8?我对这些转换有什么不了解的地方?

我发布这个问题是因为寻找答案把我带到了这里,我找到了更多信息。

pandas 时区转换功能似乎基于IANA Time Zone Database

在时区数据库的etcetera文件中是方便的注释

与区域名称中的 POSIX TZ 设置保持一致, 尽管这与许多人的期望相反。 POSIX 在格林威治以西有积极迹象,但很多人期待 格林威治以东的积极迹象。例如,TZ='Etc/GMT+4' 使用 缩写“-04”,对应于 UT 后 4 小时 (即格林威治以西),尽管许多人会期望它 平均比 UT 早 4 小时(即格林威治以东)。

另见Wikipedia entry for IANA time zones,上面写着

“Etc”这个特殊区域用于一些行政区,特别是“Etc/UTC”,它代表协调世界时。为了符合 POSIX 风格,以“Etc/GMT”开头的区域名称的符号与标准 ISO 8601 约定相反。在“Etc”区域中,GMT 以西的区域带有正号,东部的区域带有负号(例如“Etc/GMT-14”比 GMT 早 14 小时)。

【讨论】:

不幸的是,我的问题似乎真的是两个问题,其中一些可能没有答案。然而,这是一个很好的信息。很久以前,我不得不与翻转的标志和平相处……至少现在我知道这是故意的。【参考方案2】:

如果由于没有冗余值而无法使用“推断”,则可以传入一个布尔数组来指示日光时间是否有效(在这种情况下假设它无效)

print(tndx.tz_localize('US/Pacific',ambiguous=[False, False, False]).tz_convert('Etc/GMT+8'))

根据文档,此标志仅适用于在这种情况下您只有 1 个的模棱两可的时间。

然后得到天真的时间戳

print(tndx.tz_localize('US/Pacific',ambiguous=[False, False, False]).tz_localize(None))

【讨论】:

以上是关于在熊猫中从天真的本地夏令时转换为天真的本地标准时间的主要内容,如果未能解决你的问题,请参考以下文章

如何在熊猫中使用 read_csv 将时区感知日期时间作为时区天真的本地 DatetimeIndex 读取?

R将年-月-日-小时本地标准时间转换为UTC

如何添加关于夏令时时区的每周时间增量

如何在 R 中将山地标准时间 (MST) 转换为山地夏令时间 (MDT)

如何在 Dynamics CRM 中获取时区的夏令时开始和结束?

Windows 上“GTB 标准时间”的夏令时转换开始时间测试失败