Python带时区DateTime对象时间运算不一致性问题咨询
Python带时区DateTime对象的夏令时边界运算异常疑问
令人意外的是,Python的带时区DateTime对象的时间运算表现不符合预期。例如以下代码创建了一个2022-10-30 02:00的带时区对象:
from datetime import datetime, timezone, timedelta from zoneinfo import ZoneInfo zone = ZoneInfo("Europe/Madrid") HOUR = timedelta(hours=1) u0 = datetime(2022, 10, 30, 2, tzinfo=zone)
当日时间2:59时,时钟回拨至2:00,标志夏令时(DST)结束,这导致2022-10-30 02:00的时间存在歧义——该时刻出现两次:先是夏令时实例2022-10-30 02:00:00+02:00(CEST时区),随后切换为冬令时实例2022-10-30 02:00:00+01:00(CET时区)。Python通过选择夏令时的实例来解决歧义,可通过打印验证:
>>> print(u0) 2022-10-30 02:00:00+02:00 >>> u0.tzname() 'CEST'
若给u0加上1小时,程序正确识别到切换至CET时区:
>>> u1 = u0 + HOUR >>> u1.tzname() 'CET'
但时间并未如预期回拨至2:00:
>>> print(u1) 2022-10-30 03:00:00+01:00 'CET'
添加1小时的时间间隔后,实际相当于过去了2小时(本地时间从2:00到3:00,时区偏移向UTC调整1小时),而预期结果应为2022-10-30 02:00:00+01:00。转换为UTC时间可验证这一点:
>>> u0.astimezone(timezone.utc) datetime.datetime(2022, 10, 30, 0, 0, tzinfo=datetime.timezone.utc) >>> u1.astimezone(timezone.utc) datetime.datetime(2022, 10, 30, 2, 0, tzinfo=datetime.timezone.utc)
更严重的是,u1与u0的时间间隔计算会因所选时区不同而不一致:
>>> u1 - u0 datetime.timedelta(seconds=3600)
结果为1小时;而转换为UTC计算时:
>>> u1.astimezone(timezone.utc) - u0.astimezone(timezone.utc) datetime.timedelta(seconds=7200)
结果为2小时。
综上,Python对带时区DateTime对象的timedelta运算更侧重本地时钟时间,而非一致的逻辑时间间隔,跨夏令时边界时会出现差异。
zoneinfo库的存在易让人误以为此类问题已解决,该现象令人困惑。请问:
- 这是bug还是预期行为?
- 是否有其他开发者遇到过该问题,如何在应用中处理这些差异?
- 若为预期行为,Python文档是否应补充更明确的指引或警告?
编辑:已在Python 3.11和3.12版本验证该行为,在Europe/Athens等其他时区也得到类似结果,但未覆盖所有时区。
内容的提问来源于stack exchange,提问作者zap
相关产品推荐
相关产品推荐

