You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python datetime包夏令时场景下时间差计算异常问题

夏令时切换下的Python时间差计算问题

阿姆斯特丹在2023年3月26日进入夏令时,3月25日时区为UTC+1,3月26日变为UTC+2。当地时间2023年3月26日8点减去3月25日8点,实际物理时间差应为23小时,但直接用带时区的datetime对象相减却得到24小时,这是因为初始化时间的方式存在问题。

问题复现代码

from datetime import datetime, timedelta
import pendulum

p1 = datetime(year=2023, month=3, day=25, hour=8, minute=0, tzinfo=pendulum.timezone('Europe/Amsterdam')) # 非夏令时
p2 = datetime(year=2023, month=3, day=26, hour=8, minute=0,  tzinfo=pendulum.timezone('Europe/Amsterdam')) # 夏令时

print((p2 - p1).total_seconds()/3600) # 输出24.0

原因分析

直接通过datetime(..., tzinfo=...)给时间对象附加时区时,Python的datetime模块(包括pendulum提供的时区实现)只会做表层的时区标签绑定,不会对时间点进行完整的本地化解析。它默认按照日历时间计算差值:26日8点减25日8点,直接得出24小时,没有考虑夏令时切换导致的时区偏移变化。

而转换为UTC或使用时间戳计算时,会将时间转换为统一的UTC基准,此时会应用对应时间点的正确时区偏移(3月25日8点=UTC7点,3月26日8点=UTC6点),从而得到准确的23小时差值:

# 转换为UTC计算
(p2.astimezone(pendulum.timezone('UTC')) -  p1.astimezone(pendulum.timezone('UTC'))).total_seconds()/3600 # 输出23.0
# 用时间戳计算
(p2.timestamp() - p1.timestamp())/3600 # 输出23.0

正确的解决方式

不要用datetime结合tzinfo参数初始化带时区的时间,而是使用时区库提供的本地化方法,让时区正确解析时间点对应的偏移:
以pendulum为例,直接使用pendulum.datetime()构造函数:

import pendulum

p1 = pendulum.datetime(2023, 3, 25, 8, 0, tz='Europe/Amsterdam')
p2 = pendulum.datetime(2023, 3, 26, 8, 0, tz='Europe/Amsterdam')

print((p2 - p1).total_seconds()/3600) # 输出23.0

这种方式会让pendulum自动处理夏令时切换逻辑,计算出正确的物理时间差。

内容的提问来源于stack exchange,提问作者D. Zhai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:35:25