【发布时间】:2022-09-23 19:03:03
【问题描述】:
我有一个数据框,包括列Date 和Time,它们是本地时钟读数(作为字符串)。以及dst 列,它指示夏令时是否启用,W 用于冬季,S用于夏季。
我知道时区是Europe/Berlin,导致冬季从 UTC 偏移 1 小时,夏季偏移 2 小时。
我对这种表示非常不满意,并希望转换为 UTC 中的感知日期时间对象,并且只在需要时提供人类可读的时间。
Date Time dst
27.03.2022 01:15:00 W
27.03.2022 01:30:00 W
27.03.2022 01:45:00 W
27.03.2022 03:00:00 S
27.03.2022 03:15:00 S
27.03.2022 03:30:00 S
27.03.2022 03:45:00 S
27.03.2022 04:00:00 S
27.03.2022 04:15:00 S
27.03.2022 04:30:00 S
27.03.2022 04:45:00 S
27.03.2022 05:00:00 S
27.03.2022 05:15:00 S
我的第一种方法是,使用 pandas 检索一个日期时间对象,对其进行本地化并根据给定的 dst 减去两个或一个小时,使用 numpy.
from datetime import datetime, timedelta, timezone
from dateutil import tz
import numpy as np
import pandas as pd
df[\'datetime\'] = pd.to_datetime(df[\'Date\'] + df[\'Time\'], format=\'%d.%m.%Y%H:%M:%S\')
df[\'datetime_aware\'] = df[\'datetime\'].dt.tz_localize(tz=\'Europe/Berlin\')
df[\'datetime_aware_subtracted\'] = np.where(df[\'dst\']==\'S\', df[\'datetime_aware\']-timedelta(hours=2),
df[\'datetime_aware\']-timedelta(hours=1))
这会产生几乎正确的结果,除了在 03:00 - 05:00(datetime)之间,datetime_aware_subtracted 列会产生错误的结果。减去一小时太多 + 一小时时移太少。我觉得在 dst 边界上减去时间不是一个好主意。
datetime datetime_aware datetime_aware_subtracted
27.03.2022 01:15 2022-03-27 01:15:00+01:00 2022-03-27 00:15:00+01:00
27.03.2022 01:30 2022-03-27 01:30:00+01:00 2022-03-27 00:30:00+01:00
27.03.2022 01:45 2022-03-27 01:45:00+01:00 2022-03-27 00:45:00+01:00
27.03.2022 03:00 2022-03-27 03:00:00+02:00 2022-03-27 00:00:00+01:00
27.03.2022 03:15 2022-03-27 03:15:00+02:00 2022-03-27 00:15:00+01:00
27.03.2022 03:30 2022-03-27 03:30:00+02:00 2022-03-27 00:30:00+01:00
27.03.2022 03:45 2022-03-27 03:45:00+02:00 2022-03-27 00:45:00+01:00
27.03.2022 04:00 2022-03-27 04:00:00+02:00 2022-03-27 01:00:00+01:00
27.03.2022 04:15 2022-03-27 04:15:00+02:00 2022-03-27 01:15:00+01:00
27.03.2022 04:30 2022-03-27 04:30:00+02:00 2022-03-27 01:30:00+01:00
27.03.2022 04:45 2022-03-27 04:45:00+02:00 2022-03-27 01:45:00+01:00
27.03.2022 05:00 2022-03-27 05:00:00+02:00 2022-03-27 03:00:00+02:00
27.03.2022 05:15 2022-03-27 05:15:00+02:00 2022-03-27 03:15:00+02:00
我的第二种方法,是逆减法和本地化。
df[\'datetime\'] = pd.to_datetime(df[\'Date\'] + df[\'Time\'], format=\'%d.%m.%Y%H:%M:%S\')
df[\'datetime_subtracted\'] = np.where(df[\'dst\']==\'S\', df[\'datetime\']-timedelta(hours=2),
df[\'datetime\']-timedelta(hours=1))
df[\'datetime_subtracted_aware\'] = df[\'datetime_subtracted\'].dt.tz_localize(tz=\'Europe/Berlin\')
这给出了正确的幼稚结果,但在本地化时减去后给出NonExistentTimeError(理所当然)。
Traceback (most recent call last):
File \"<stdin>\", line 1, in <module>
File \"C:\\ProgramData\\Miniconda3\\envs\\env\\lib\\site-packages\\pandas\\core\\accessor.py\", line 94, in f
return self._delegate_method(name, *args, **kwargs)
File \"C:\\ProgramData\\Miniconda3\\envs\\env\\lib\\site-packages\\pandas\\core\\indexes\\accessors.py\", line 123, in _delegate_method
result = method(*args, **kwargs)
File \"C:\\ProgramData\\Miniconda3\\envs\\env\\lib\\site-packages\\pandas\\core\\indexes\\datetimes.py\", line 273, in tz_localize
arr = self._data.tz_localize(tz, ambiguous, nonexistent)
File \"C:\\ProgramData\\Miniconda3\\envs\\env\\lib\\site-packages\\pandas\\core\\arrays\\_mixins.py\", line 84, in method
return meth(self, *args, **kwargs)
File \"C:\\ProgramData\\Miniconda3\\envs\\env\\lib\\site-packages\\pandas\\core\\arrays\\datetimes.py\", line 1043, in tz_localize
new_dates = tzconversion.tz_localize_to_utc(
File \"pandas\\_libs\\tslibs\\tzconversion.pyx\", line 328, in pandas._libs.tslibs.tzconversion.tz_localize_to_utc
pytz.exceptions.NonExistentTimeError: 2022-03-27 02:00:00
在Europe/Berlin 时区了解UTC 日期时间对象的最佳选择是什么?
-
永远不要根据您认为自己知道的有关时区的任何信息手动添加或减少时间。总是得到一个时区库来为你做这件事。 gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b923ca
标签: python pandas datetime timezone