Python 3.7中datetime.min时区处理报错:是Bug还是预期行为?
datetime.min时区转换异常的原因分析
代码复现
执行astimezone()进行时区转换时的异常:
>>> datetime.max.astimezone(pytz.UTC) datetime.datetime(9999, 12, 31, 23, 59, 59, 999999, tzinfo=<UTC>) >>> datetime.min.astimezone(pytz.UTC) ValueError: year 0 is out of range
使用replace()设置时区则正常:
>>> datetime.min.replace(tzinfo=pytz.UTC) datetime.datetime(1, 1, 1, 0, 0, tzinfo=<UTC>)
结论:这是预期行为
两者的差异源于两个方法的核心逻辑完全不同:
replace()是静态属性替换:仅直接修改datetime对象的tzinfo属性,不做任何日期时间数值的计算,因此给datetime.min(公元1年1月1日)直接附加UTC时区信息后,能正常返回合法的datetime对象。astimezone()是动态时区转换:当原datetime对象没有tzinfo时,会默认将其视为本地时区时间,再转换为目标时区UTC。而datetime.min对应的本地时区时间在转换过程中,会因历史时区规则的偏移计算,导致结果落到公元0年——但Python的datetime模块不支持公元0年(公历体系中不存在公元0年,直接从公元前1年过渡到公元1年),因此抛出year 0 is out of range的错误。
datetime.max因数值足够大,转换时不会触发跨公元0年的计算问题,因此能正常完成时区转换。
内容的提问来源于stack exchange,提问作者C. Claudio
相关产品推荐
相关产品推荐

