18

出力をとと比較する際に問題がdateutilありpytzます。認識された日時オブジェクト(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はnormalizeDSTを考慮する必要がありますか?

更新2:

pytzとdateutilはAmerica/Argentina / San_Luisの答えを出さないように見えましたが、これは機能します。

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

私は何かが足りないのですか?

ありがとう

4

1 に答える 1

16

編集:以下で説明する不一致は、使用時に存在しなくなりました

>>> dateutil.__version__
'1.5'

>>> pytz.__version__
'2012c'

pytzモジュールは警告します、

このライブラリは、tzinfo実装用に文書化されたPythonAPIとは異なります。ローカルウォールクロック時間を作成する場合は、localize()メソッドを使用する必要があります

そしてさらに

このライブラリは、ローカライズされた時間を構築する2つの方法のみをサポートします。1つは、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

もう1つの方法は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は正しいようです。

于 2012-12-19T02:49:18.310 に答える