我在将输出与dateutil
和pytz
进行比较时遇到问题。我正在创建一个aware datetime对象(UTC),然后将其转换为给定的时区,但是我得到了不同的答案。我怀疑dateutil有时会给出错误的结果,因为它在考虑夏令时时存在问题(至少,我读到了关于它的评论),但我找不到确认或解决这个问题的方法。代码如下:
import dateutil
u = dateutil.tz.tzutc()
date1 = datetime.datetime(2010, 5, 2, 11, 10, tzinfo=u)
# 2010-05-02 11:10:00+00:00
u2 = dateutil.tz.gettz('America/Chicago')
date2 = datetime.datetime(2010, 5, 2, 11, 10, tzinfo=u2)
# 2010-05-02 11:10:00-05:00
import pytz
u = pytz.timezone('UTC')
date1 = datetime.datetime(2010, 5, 2, 11, 10, tzinfo=u)
# 2010-05-02 11:10:00+00:00
u2 = pytz.timezone('America/Chicago')
date2 = datetime.datetime(2010, 5, 2, 11, 10, tzinfo=u2)
# 2010-05-02 11:10:00-06:00
那么,这里会有什么问题呢?
更新:
我刚试过这个:
print u2.normalize(date1.astimezone(u2))
# 2010-05-02 06:10:00-05:00
所以pytz需要normalize
来考虑DST?
更新2:
似乎pytz和dateutil没有给出美国/阿根廷/圣路易斯的答案,但这是可行的:
import pytz, dateutil, datetime
now = datetime.datetime.now()
for zone in pytz.all_timezones:
utc_dateutil = dateutil.tz.tzutc()
utcdate_dateutil = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, tzinfo=utc_dateutil)
zone_dateutil = dateutil.tz.gettz(zone)
newzone_dateutil = utcdate_dateutil.astimezone(zone_dateutil)
utc_pytz = pytz.timezone('UTC')
utcdate_pytz = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, tzinfo=utc_pytz)
zone_pytz = pytz.timezone(zone)
newzone_pytz = utcdate_pytz.astimezone(zone_pytz)
assert newzone_dateutil == newzone_pytz
我是不是遗漏了什么?
谢谢
发布于 2012-12-19 10:49:18
编辑:以下讨论的差异在使用时不再存在
>>> dateutil.__version__
'1.5'
>>> pytz.__version__
'2012c'
pytz模块warns,
这个库不同于文档中的用于tzinfo实现的Python API;如果您想要创建本地挂钟时间,则需要使用localize()方法
这个库只支持两种构建本地化时间的方式。第一种方法是使用pytz库提供的localize()方法。
In [61]: u4 = pytz.timezone('America/Chicago')
In [62]: print(u4.localize(datetime.datetime(2010, 5, 2, 11, 10)))
2010-05-02 11:10:00-05:00
另一种方法是使用astimezone
方法,该方法用于将支持时区的datetime转换为另一个支持时区的datetime。
更明确地说,它使用tzinfo
参数warns against构造了一个时区感知的datetime:
不幸的是,在许多时区中,使用标准datetime构造函数的
参数“不适用于”pytz。
让我们测试一下假设
datetime.datetime(year, month, day, hour, minute, tzinfo = dateutil_tz)
等于
pytz_tz.localize(datetime.datetime(year, month, day, hour, minute))
使用以下代码:
import dateutil.tz
import datetime
import pytz
now = datetime.datetime.now()
for name in pytz.all_timezones:
dateutil_tz = dateutil.tz.gettz(name)
pytz_tz = pytz.timezone(name)
dateutil_date = datetime.datetime(
now.year, now.month, now.day, now.hour, now.minute, tzinfo = dateutil_tz)
pytz_date = pytz_tz.localize(datetime.datetime(
now.year, now.month, now.day, now.hour, now.minute))
try:
assert dateutil_date.isoformat() == pytz_date.isoformat()
except AssertionError:
print(name)
print(dateutil_date.isoformat())
print(pytz_date.isoformat())
代码生成:
America/Argentina/San_Luis
2012-12-18T22:32:00-04:00 <-- dateutil datetime
2012-12-18T22:32:00-03:00 <-- pytz's datetime
所以我的假设是错误的: dateutil和pytz返回不同的结果。
那么哪一个是正确的呢?我不是很确定,但根据this website的说法,目前
America/Argentina/San_Luis time zone offset is:
UTC / GMT -03:00 hours
所以看起来pytz是正确的。
https://stackoverflow.com/questions/13944688
复制相似问题