pytz问题:tz_convert()没有给出未来正确的(夏季)时间



我担心pytz的一个奇怪行为,在未来的日期中使用tz_convert()

更准确地说,给定UTC时间戳:'2046-05-31 22:00:00+00:00',转换为"UTC";欧洲/巴黎";时区:

pd.to_datetime(pd.Index(pd.Series('2046-05-31 22:00:00+00:00'))).tz_convert('Europe/Paris')

返回

DatetimeIndex(['2046-05-31 23:00:00+01:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)

而它应该返回

DatetimeIndex(['2046-06-01 00:00:00+02:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)

pytz在巴黎将2046年6月解释为中欧时间(+01(,而不是中欧夏令时间(+02(。例如,使用'2026-05-31 22:00:00+00:00'尝试以上操作会返回CEST时间。问题似乎是pytz不知道未来CEST和CET的日期。

例如,当试图将本地化的时间戳转换为特定位置的日期时,这是有问题的。

这是意料之中的事吗?有没有办法避免这个问题?

注意:即使熊猫也参与其中,这似乎是一个pytz问题,因为datetime.fromisoformat('2046-05-31 22:00:00+00:00').astimezone(pytz.timezone("Europe/Paris"))返回的是CET时间,而不是CEST。

我对pytz和2038年之后的未来日期(在我的情况下是2040年(也有类似的问题。对于初始化,这对我很有效。也许你可以以某种方式调整它,或者其他人知道如何使用ZoneInfo转换时间字符串。

from datetime import datetime
from zoneinfo import ZoneInfo
# from year, month, day, hour, second
dt = datetime(2040, 6, 1, 0, 0, 0, tzinfo=ZoneInfo('Europe/Paris'))
# from unixtimestamp
dt2 = datetime.fromtimestamp(2411416800, ZoneInfo('Europe/Paris'))
# both return
# datetime.datetime(2040, 6, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))

编辑:我也试着按照你的问题中的要求转换以获得正确的DatetimeIndex,但是,这似乎不可能。。。

import pandas as pd
from datetime import datetime
from zoneinfo import ZoneInfo
time_string_input = '2046-05-31 22:00:00+00:00'
# pytz conversion doesn't work
datetime_index_1 = pd.to_datetime(pd.Index(pd.Series(time_string_input))).tz_convert('Europe/Paris')
# DatetimeIndex(['2046-05-31 23:00:00+01:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)

# Alternative: convert with datetime + ZoneInfo
str_format = "%Y-%m-%d %H:%M:%S%z"
unixtimestamp_2 = datetime.strptime(time_string_input, str_format).timestamp()
# 2411416800.0
datetime_2 = datetime.fromtimestamp(unixtimestamp_2, ZoneInfo('Europe/Paris'))
# datetime.datetime(2046, 6, 1, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Paris'))
time_string_2 = datetime_2.strftime(str_format)
# '2046-06-01 00:00:00+0200'
time_string_2_with_tz_colon = time_string_2[:-2] + ":" + time_string_2[-2:]
# '2046-06-01 00:00:00+02:00'
datetime_index_fixed_2 = pd.to_datetime(pd.Index(pd.Series(time_string_2_with_tz_colon)))
# DatetimeIndex(['2046-06-01 00:00:00+02:00'], dtype='datetime64[ns, pytz.FixedOffset(120)]', freq=None)
datetime_index_2 = datetime_index_fixed_2.tz_convert('Europe/Paris')
# DatetimeIndex(['2046-05-31 23:00:00+01:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)

所以,当你可以得到

DatetimeIndex(['2046-06-01 00:00:00+02:00'], dtype='datetime64[ns, pytz.FixedOffset(120)]', freq=None)

有了固定的偏移量,你就无法获得格式的偏移量

DatetimeIndex(['2046-06-01 00:00:00+02:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)

根据需要。。。

我建议在代码中使用unixtimestamp(例如,在pandas数据帧索引中(,并且只在数据进出程序时使用时区。

第页。S.:如果有人在使用matplotlib绘制数据帧时遇到2K38相关问题(即使时间戳是正确的(,也许这会有所帮助:https://github.com/matplotlib/matplotlib/issues/17538#issuecomment-1562663533

最新更新