为啥萨摩亚的 pytz 和 dateutil 得到不同的结果?
Posted
技术标签:
【中文标题】为啥萨摩亚的 pytz 和 dateutil 得到不同的结果?【英文标题】:Why do I get different results for pytz and dateutil for Samoa?为什么萨摩亚的 pytz 和 dateutil 得到不同的结果? 【发布时间】:2019-02-07 18:10:06 【问题描述】:我原以为以下两个会给出相同的结果,但事实并非如此。为什么会这样?
版本:
pytz==2018.5
python-dateutil==2.7.3
示例 1:pytz
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
(正确)
示例 2:dateutil
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
(这是错误的)
【问题讨论】:
为什么说-10是对的,+14是不对的? This page 说 Pacific/Apia 通常是 UTC+13,而 DST 是 UTC+14。 因为 2011-12-29 是-10。他们改变了时区。见timeanddate.de/stadt/zeitzone/samoa/apia lol 没想到...所以,您期望 dateutil 应该能够根据日期更改时区。也许它根本不这样做。 @zvone 所有偏移量取决于日期 @zvone 好吧,可能是这样。但我想从某人那里听到/在这里获得参考。目前,我假设我只是以错误的方式使用 dateutil 。如果它不能处理同一时区内的偏移量变化(我之前措辞很糟糕),那就太糟糕了。它经常发生。 【参考方案1】:你发现了一个bug in dateutil
,我现在已经报告了它和fixed。
该错误是由 dateutil
中如何计算转换的“墙壁时间”的问题引起的,当时区的基本偏移量在 DST 期间发生变化时,该假设不成立。稍微扩展您的示例:
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 和本地时间存储转换时间,fromutc
使用 UTC 时间,utcoffset
、dst
和 tzname
使用本地时间。此错误涉及在计算 DST->DST 转换期间转换的“墙壁时间”时过度补偿 DST(这非常罕见),这就是它不影响 astimezone
的原因。
底线 - 您正确使用了 pytz
和 dateutil
,此错误将在下一个版本中修复。
注意:这个答案是在我找到错误的原因并修复后编辑的。
【讨论】:
以上是关于为啥萨摩亚的 pytz 和 dateutil 得到不同的结果?的主要内容,如果未能解决你的问题,请参考以下文章