与pytz时区的datetime.不同的偏移量取决于tzinfo的设置方式

Duk*_*ver 2 python timezone datetime pytz

我今天遇到了一个有趣的情况.谁能解释为什么ts1和ts2的偏移量不同?ts1是一个日期时间对象,可立即识别时区.ts2是一个日期时间对象,它从时区开始并且替换了tzinfo.然而,他们最终得到不同的抵消.

>>> 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
Run Code Online (Sandbox Code Playgroud)

dan*_*ano 10

当你打电话时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>)
Run Code Online (Sandbox Code Playgroud)

你最终得到LMT而不是EDT.

pytz 文档实际上指出,使用标准日期时间对象pytztzinfo参数根本不适用于许多时区:

不幸的是,对于许多时区,使用标准日期时间构造函数的'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'

我不确定为什么第一个有效; 也许是因为当对象最初用tzinfo对象构造时,它实际上不需要转换任何东西.

编辑:

啊,Python 文档指出datetime.datetime.now()tzarg 一起使用相当于:

EST.fromutc(datetime.utcnow().replace(tzinfo=EST))
Run Code Online (Sandbox Code Playgroud)

这意味着你要从UTC转换,这是安全的pytz.所以这就是第一个有效的原因.


Mat*_*int 5

根据文档,将时区应用于原始日期时间的正确方法是该localize方法。

ts1 = eastern.localize(datetime.datetime.now())
Run Code Online (Sandbox Code Playgroud)

另外,我建议您使用void EST作为变量名,因为它通常是“东部标准时间”的标准名称,并且同时America/New_York包含“东部标准时间”(EST)和“东部夏令时间”(EDT)。

  • 在DST转换期间可能会返回不正确的结果,请改用`datetime.now(eastern)`。 (2认同)