dateutil和pytz给出不同的结果 [英] dateutil and pytz give different results

查看:178
本文介绍了dateutil和pytz给出不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,比较输出与 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


更新:



我刚刚尝试过:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆