使用pytz时区的datetime。根据tzinfo设置的不同而有不同的偏移量

3 投票
2 回答
8487 浏览
提问于 2025-04-18 06:46

今天我遇到了一个有趣的情况。有没有人能解释一下为什么ts1和ts2的偏移量不同?ts1是一个一开始就知道时区的日期时间对象。而ts2是一个一开始不知道时区的日期时间对象,后来它的时区信息被替换了。不过,最后它们的偏移量却不一样。

>>> from pytz import timezone
>>> EST = timezone('America/New_York')
>>> ts1 = datetime.datetime.now(tz=EST)
>>> ts2 = datetime.datetime.now()
>>> ts2 = ts2.replace(tzinfo=EST)
>>> print ts1
2014-05-16 11:25:16.749748-04:00
>>> print ts2
2014-05-16 11:25:19.581710-05:00

2 个回答

5

根据文档,给一个没有时区信息的日期时间加上时区的正确方法是使用localize这个方法。

ts1 = eastern.localize(datetime.datetime.now())

另外,我建议你不要用EST作为变量名,因为它通常代表“东部标准时间”,而America/New_York则包含了“东部标准时间”(EST)和“东部夏令时间”(EDT)这两种时间。

11

当你调用 ts2.replace(tzinfo=EST) 时,你得到的 tzinfo 对象和 ts1 的不一样:

>>> ts1
datetime.datetime(2014, 5, 16, 11, 51, 7, 916090, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)
>>> ts2
datetime.datetime(2014, 5, 16, 11, 51, 30, 922692, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)

结果你得到的是 LMT,而不是 EDT。

pytz文档 实际上提到,使用 pytz 和标准日期时间对象的 tzinfo 参数在很多时区下根本不管用:

不幸的是,标准日期时间构造函数的 tzinfo 参数在很多时区下与 pytz ''不兼容''。

>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt) '2002-10-27 12:00:00 LMT+0020'

不过,对于没有夏令时转换的时区,比如 UTC,使用是安全的:

>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt) '2002-10-27 12:00:00 UTC+0000'

我不太确定第一个能用的原因;也许是因为在最初构造这个对象时,它实际上不需要转换任何东西。

编辑

哦,Python 的 文档 提到,使用 datetime.datetime.now()tz 参数是等同于:

EST.fromutc(datetime.utcnow().replace(tzinfo=EST))

这意味着你是从 UTC 转换,这在使用 pytz 时是安全的。所以这就是第一个能用的原因。

撰写回答