Python datetime对象显示错误的时区偏移
我正在尝试在Python中使用datetime和pytz创建一个日期时间对象,但显示的时区偏移是错误的。
import datetime
from pytz import timezone
start = datetime.datetime(2011, 6, 20, 0, 0, 0, 0, timezone('Asia/Kolkata'))
print start
输出结果是
datetime.datetime(2011, 6, 20, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' HMT+5:53:00 STD>)
请注意,'Asia/Kolkata'是印度标准时间(IST),它是GMT+5:30,而不是HMT+5:53。这是一个标准的Linux时区,为什么我会得到这个错误的结果,我该如何解决呢?
2 个回答
9
在Python 3.9及以上版本中,这个问题已经通过标准库中的zoneinfo模块解决了。对于3.9及以上的版本,建议停止使用pytz库。
In [1]: import datetime
In [2]: from zoneinfo import ZoneInfo
In [3]: start = datetime.datetime(2011, 6, 20, 0, 0, 0, 0, ZoneInfo('Asia/Kolkata'))
In [4]: print(start)
2011-06-20 00:00:00+05:30
之所以会出现这种让人困惑的情况,是因为在过去,时区的标准并不是统一的,像是:30或:00的偏移量。大约在20世纪初,大部分时区开始采用统一的偏移量。在提问者的例子中,时区在1906年发生了变化。而对于美国中部时区,这个变化是在1901年。
from datetime import datetime, timedelta, date
from pytz import timezone
d = datetime.combine(date.today(), time.min)
for tz in ('Asia/Kolkata', "US/Central"):
while d > datetime(1800, 1, 1):
localized = timezone(tz).localize(d)
if localized.isoformat()[-2:] not in ("00", "30"):
print(tz)
print(localized.isoformat())
print(timezone(tz).localize(d + timedelta(days=1)).isoformat())
break
d -= timedelta(days=1)
这段代码的输出是:
Asia/Kolkata
1906-01-01T00:00:00+05:21
1906-01-02T00:00:00+05:30
US/Central
1901-12-13T00:00:00-05:51
1901-12-14T00:00:00-06:00
Pytz似乎在没有日期信息的情况下,只会使用最早的偏移量,即使那个时间已经过去很久。在一些很自然的用法中,比如把tzinfo传递给datetime构造函数,时区对象并没有得到这些数据。
99
请查看:http://bytes.com/topic/python/answers/676275-pytz-giving-incorrect-offset-timezone
在评论中,有人建议使用 tzinfo.localize()
来代替 datetime
的构造函数,这样就能解决问题。
>>> tz = timezone('Asia/Kolkata')
>>> dt = tz.localize(datetime.datetime(2011, 6, 20, 0, 0, 0, 0))
>>> dt
datetime.datetime(2011, 6, 20, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>)
更新:实际上,pytz的官方网站指出,你应该始终使用 localize
或 astimezone
,而不是直接把时区对象传给 datetime.datetime
。