我期望以下两个结果相同,但事实并非如此。为什么会这样呢?
版本:
pytz==2018.5
python-dateutil==2.7.3
import datetime
import pytz
tz = pytz.timezone('Pacific/Apia')
today_utc = datetime.datetime(2011, 12, 30, 9, 59,
tzinfo=datetime.timezone.utc)
today_tz = today_utc.astimezone(tz)
print(today_tz.isoformat())
打印2011-12-29T23:59:00-10:00
(正确)
import datetime
import dateutil.tz
tz = dateutil.tz.gettz('Pacific/Apia')
today_utc = datetime.datetime(2011, 12, 30, 9, 59,
tzinfo=datetime.timezone.utc)
today_tz = today_utc.astimezone(tz)
print(today_tz.isoformat())
打印2011-12-29T23:59:00+14:00
(这是错误的)
答案 0 :(得分:2)
您发现了一个bug in dateutil
,我现在已经将其报告为fixed。
该错误是由于在dateutil
中如何计算转换的“墙时”而引起的,该问题做出了一些假设,而这些假设在DST < / em>。扩展您的示例:
from datetime import datetime, timedelta
from dateutil import tz
import pytz
APIA = tz.gettz('Pacific/Apia')
APIA_p = pytz.timezone('Pacific/Apia')
dt0 = datetime.fromisoformat('2011-12-29T20:00-10:00')
for i in range(5):
dt = (dt0 + timedelta(hours=i))
dt_d = dt.astimezone(APIA)
dt_p = dt.astimezone(APIA_p)
print(f'{dt_d.isoformat()}, {dt_p.isoformat()}')
## Result:
# 2011-12-29T20:00:00-10:00, 2011-12-29T20:00:00-10:00
# 2011-12-29T21:00:00-10:00, 2011-12-29T21:00:00-10:00
# 2011-12-29T22:00:00-10:00, 2011-12-29T22:00:00-10:00
# 2011-12-29T23:00:00+14:00, 2011-12-29T23:00:00-10:00
# 2011-12-31T00:00:00+14:00, 2011-12-31T00:00:00+14:00
您可以看到dateutil
总是可以正确计算日期和时间,但是当isoformat
调用utcoffset
时,偏移量更改会提前1小时发生。这是因为astimezone
会在后台调用tzinfo.fromutc
,而isoformat
会调用utcoffset
。 dateutil
将转换时间存储在UTC和本地时间中,UTC时间用在fromutc
中,本地时间用在utcoffset
,dst
和{{1}中}。该错误涉及在DST-> DST过渡期间计算过渡的“时间”(这非常少见)时过度补偿了DST,这就是为什么它不影响tzname
的原因。
底线-您同时正确使用astimezone
和pytz
,此错误将在下一版本中得到解决。
注意:在我找到了引起该错误的原因并修复该错误之后,对该答案进行了编辑。