dateutil和pytz为什么给出了不同的结果?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (40)

我有一个问题比较输出dateutilpytz。我创建一个有意识的日期时间对象(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:

这是有效的:

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

我错过了什么吗?

谢谢

提问于
用户回答回答于

使用时,差异不再存在

>>> dateutil.__version__
'1.5'

>>> pytz.__version__
'2012c'

Pytz模块警告说

这个库与用于tzinfo实现的记录的Python API不同; 如果你想创建本地wallclock时间,你需要使用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方法,该方法用于将可识别时区的日期时间转换为另一个可识别时区的日期时间。

为了完全明确,它警告不要使用tzinfo参数构建可识别时区的日期时间:

不幸的是,对于许多时区,使用标准日期时间构造函数的tzinfo参数“不适用”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返回不同的结果。

那么哪一个是正确的?我不确定,但根据这个网站,目前,

America/Argentina/San_Luis time zone offset is: 
UTC / GMT -03:00 hours

所以看起来pytz是正确的。

所属标签

可能回答问题的人

  • 人生的旅途

    10 粉丝484 提问5 回答
  • 无聊至极

    4 粉丝504 提问5 回答
  • 嗨喽你好

    7 粉丝480 提问4 回答
  • 富有想象力的人

    4 粉丝0 提问4 回答

扫码关注云+社区

领取腾讯云代金券