为何转换时区后部分Python datetime对象比较结果不相等?
时区转换后Datetime对象比较返回False的原因
夏令时前进(跳过时间)场景
代码示例
from datetime import datetime, timedelta from zoneinfo import ZoneInfo chi = ZoneInfo("America/Chicago") nyc = ZoneInfo("America/New_York") dt1 = datetime(2024, 3, 10, 3, 30, tzinfo=chi) dt2 = datetime(2024, 3, 10, 2, 30, tzinfo=chi) print(dt1 == dt1.astimezone(nyc)) print(dt2 == dt2.astimezone(nyc))
运行结果
True False
原因分析
美国中部时区(Chicago)在2024年3月10日凌晨2点会执行夏令时前进调整:时钟直接从2点跳到3点,2:00到3:00之间的所有时间都是不存在的无效时间。
dt1的3:30是夏令时调整后的有效时间,转换到纽约时区后本质对应同一个UTC时间点,因此比较返回True。dt2的2:30是完全不存在的时间,直接用tzinfo=chi创建该对象时,Python无法将其映射到真实时间轴,内部存储的时间戳是错误的。调用astimezone(nyc)时,Python会自动把这个无效时间修正为实际存在的时间,转换后的对象和原dt2的时间戳不一致,所以比较返回False。
夏令时回退(重复时间)场景
代码示例
from datetime import datetime, timedelta from zoneinfo import ZoneInfo chi = ZoneInfo("America/Chicago") nyc = ZoneInfo("America/New_York") dt1 = datetime(2024, 11, 3, 2, 30, tzinfo=chi) dt2 = datetime(2024, 11, 3, 1, 30, tzinfo=chi) print(dt1 == dt1.astimezone(nyc)) print(dt2 == dt2.astimezone(nyc))
原因分析
美国中部时区在2024年11月3日凌晨2点会执行夏令时回退调整:时钟从2点倒回1点,1:00到2:00之间的时间会重复出现两次(第一次是夏令时CDT,第二次是冬令时CST)。
dt1的2:30是回退后的有效时间,转换时区后对应同一个UTC时间,比较返回True。dt2的1:30是模糊时间,创建时Python默认将其解析为第一次出现的CDT时区时间;但调用astimezone(nyc)转换后再转回芝加哥时区时,会被解析为第二次出现的CST时区时间,两者对应的UTC时间不同,因此比较返回False。
总结
当创建的datetime对象对应时区中不存在的无效时间或重复的模糊时间时,直接赋值tzinfo会导致对象内部存储的时间戳与真实时间不符。而astimezone方法会自动修正这些时间到真实时间轴上,导致转换前后的对象本质对应不同时间点,比较结果为False。
内容的提问来源于stack exchange,提问作者no step on snek
相关产品推荐
相关产品推荐

