在 1901-12-13 20:45:52 UTC 之前,'Europe/Budapest' 时区是 LMT+1:16:00 STD。
目前,截至 2016 年 5 月 5 日,'Europe/Budapest' 时区为 CET+2:00:00 DST。
如果您使用 pytz 的 localize method,那么 pytz 将为 'Europe/Budapest' 选择适合给定的原始日期时间的时区(utcoffset 和 dstoffset):
import datetime as DT
import pytz
tzone = pytz.timezone('Europe/Budapest')
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None)
# datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CET+1:00:00 STD>)
相比之下,如果您将tzinfo=tzone 直接提供给datetime.datetime,如下所示:
wrong_date1 = datetime.datetime(2014, 3, 29, 0, 0, tzinfo=tzone)
# datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>)
那么datetime.datetime 错误地选择了与'Europe/Budapest' 关联的第一个时区 无论该时区是否是 2014 年 3 月 29 日生效的时区 .
因此,在使用 pytz 时,请始终使用tzone.localize 来使天真的日期时间时区感知:
import datetime as DT
import pytz
tzone = pytz.timezone('Europe/Budapest')
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None)
date2 = tzone.localize(DT.datetime(2014, 3, 30, 23, 59), is_dst=None)
print(((date2-date1) + DT.timedelta(minutes=1)).total_seconds()/3600.)
# 47.0
Do not use tzinfo=tzone 除非 tzone 是 pytz.utc(或在其历史上始终相同的时区。)
1901-12-13 20:45:52 UTC 的日期从何而来?
您可以使用其 tzone._utc_transition_times 和 tzone._transition_info 私有属性查看 pytz 时区的 utc 转换时间(以及相关的转换信息):
In [43]: [(utcdate, utcoffset, dstoffset, tzabbrev) for utcdate, (utcoffset, dstoffset, tzabbrev) in zip(tzone._utc_transition_times, tzone._transition_info)][:2]
Out[43]:
[(datetime.datetime(1, 1, 1, 0, 0),
datetime.timedelta(0, 4560),
datetime.timedelta(0),
'LMT'),
(datetime.datetime(1901, 12, 13, 20, 45, 52),
datetime.timedelta(0, 3600),
datetime.timedelta(0),
'CET')]
这表明从日期1-1-1 UTC 到1901-12-13 20:45:52 UTC,时区缩写为LMT,utcoffset 为4560 秒,等于1 小时16 分钟:
In [47]: print(DT.timedelta(0, 4560))
1:16:00
因此与'Europe/Budapest' 关联的第一个时区是LMT+1:16:00 STD。