dateutil和pytz给出不同的结果 [英] dateutil and pytz give different results
问题描述
我有一个问题,比较输出与 dateutil
和 pytz
。我正在创建一个感知的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
$ c那么,这里可能是什么问题?
更新:
我刚刚尝试过:
print u2.normalize(date1.astimezone u2))
#2010-05-02 06:10:00-05:00
所以pytz需要规范化
来考虑DST?
UPD ATE 2:
似乎pytz和dateutil不给美国/阿根廷/ San_Luis的答案,但这有用:
import pytz,dateutil,datetime
now = datetime.datetime.now()
for pyz .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
我错过了什么?
谢谢
解决方案 编辑:使用
>>以下讨论的差异不再存在> dateutil .__ version__
'1.5'
>>> pytz .__ version__
'2012c'
pytz模块警告,
此库与用于tzinfo
实现的已记录的Python API不同;如果要创建本地的wallclock时间,则需要
才能使用localize()方法
和进一步
此库仅支持构建本地化时间的两种方式。
首先是使用由pytz库提供的localize()方法。
在[62]中:print(u4.localize(datetime.datetime(2010,5,2,11,10)))
2010-05-02 11:10:00-05:00
另一种方式是使用 astimezone
方法,它用于将时区感知日期时间转换为另一个时区感知日期时间。
要完全明确,它警告构建时区-aware datetime使用 tzinfo
参数:
不幸的是使用tzinfo参数
$ b $标准的datetime
构造函数对于许多时区b
我们来试验一下这个假设:
dateti me.datetime(年,月,日,小时,分,tzinfo = dateutil_tz)
p>
pytz_tz.localize(datetime.datetime(年,月,日,小时,分))
与此代码:
import dateutil .tz
import datetime
import pytz
now = datetime.datetime.now()
在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。小时,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()
除了AssertionError:
print(name)
print(dateutil_date.isoformat ())
print(pytz_date.isoformat())
代码产生:
美国/阿根廷/ San_Luis
2012-12-18T22:32:00-04:00< - dateutil datetime
2012-12-18T22:32:00-03 :00< - pytz的datetime
所以我的假设是错误的:dateutil和pytz返回不同的结果。
那么哪一个是正确的?我不太确定,但根据本网站,目前,
美国/阿根廷/ San_Luis时区抵消是:
UTC / GMT -03:00小时
所以看起来pytz是正确的。
I have an issue comparing outputs with dateutil
and pytz
. I'm creating a aware datetime object (UTC) and then converting to a given time zone, but I get different answers. I suspect that dateutil sometimes gives wrong results because it has problems taking into account daylight saving time (at least, I read a comment about it) but I can't find confirmation or a fix to that issue. This is the code:
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
So, what could be the problem here?
UPDATE:
I just tried this:
print u2.normalize(date1.astimezone(u2))
# 2010-05-02 06:10:00-05:00
So pytz needs normalize
to consider DST?
UPDATE 2:
It seemed as if pytz and dateutil don't give the answer for America/Argentina/San_Luis but this works:
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
Am I missing something?
Thanks
Edit: The discrepancy discussed below no longer exists when using
>>> dateutil.__version__
'1.5'
>>> pytz.__version__
'2012c'
The pytz module warns,
this library differs from the documented Python API for tzinfo implementations; if you want to create local wallclock times you need to use the localize() method
and further on
This library only supports two ways of building a localized time. The first is to use the localize() method provided by the pytz library.
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
The other way is to use the astimezone
method, which is used to convert a timezone-aware datetime into another timezone-aware datetime.
And to be completely explicit, it warns against constructing a timezone-aware datetime using the tzinfo
argument:
Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.
Let's test the hypothesis that
datetime.datetime(year, month, day, hour, minute, tzinfo = dateutil_tz)
equals
pytz_tz.localize(datetime.datetime(year, month, day, hour, minute))
with this code:
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())
The code yields:
America/Argentina/San_Luis
2012-12-18T22:32:00-04:00 <-- dateutil datetime
2012-12-18T22:32:00-03:00 <-- pytz's datetime
So my hypothesis was wrong: dateutil and pytz return different results.
So which one is correct? I'm not really sure, but according to this website, currently,
America/Argentina/San_Luis time zone offset is:
UTC / GMT -03:00 hours
so it appears pytz is correct.
这篇关于dateutil和pytz给出不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!