问题
pytz 是 Python 的时区库,可用于补充标准库 datetime 对时区支持的不足。例如:
import pytz
from pytz import timezone
shanghai = timezone('Asia/Shanghai')
amsterdam = timezone('Europe/Amsterdam')
utc = pytz.UTC
若将这些时区对象直接作为 tzinfo 传入 datetime 构造函数,会出现时间偏移:
from datetime import datetime
d = datetime(2019, 1, 1, 12, 0, 0, tzinfo=shanghai)
print(d)
输出通常与预期相差几分钟(不同地区偏移量不同)。
原因
pytz 文档指出,大多数时区对象与 datetime 构造函数的 tzinfo 参数不兼容,除非该时区没有夏令时(如 UTC)。
It is safe for timezones without daylight saving transitions though, such as UTC.
正确用法
localize
对于「原生」datetime(不含时区),应使用时区对象的 localize
方法:
from datetime import datetime
from pytz import timezone
t = datetime(2019, 1, 1, 12, 0, 0)
amsterdam = timezone('Europe/Amsterdam')
ams_dt = amsterdam.localize(t)
print(ams_dt)
# 2019-01-01 12:00:00+01:00
astimezone
对于已带时区的 datetime,可使用 astimezone
转换至其他时区:
shanghai = timezone('Asia/Shanghai')
sh_dt = ams_dt.astimezone(shanghai)
print(sh_dt)
# 2019-01-01 19:00:00+08:00
结论
构造 Asia/Shanghai
等时区的时间对象时,推荐:
- 先创建原生 datetime,再调用
localize
; - 或先创建 UTC 时间,再使用
astimezone
转换。