62

pytzの.localize()関数で奇妙な問題が発生しています。ローカライズされた日時が調整されない場合があります。

.localize動作:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 
>>> d
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421)

>>> tz.localize(d)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
>>> tz.normalize(tz.localize(d))
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

ご覧のとおり、ローカライズ/正規化操作の結果として時間は変更されていません。ただし、.replaceが使用されている場合:

>>> d.replace(tzinfo=tz)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>)
>>> tz.normalize(d.replace(tzinfo=tz))
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

これは日時を調整するようです。

質問は-どちらが正しいのか、なぜ他の人が間違っているのか?

4

4 に答える 4

51

localize渡したナイーブな日時が「正しい」と想定しているため(タイムゾーンがわからない場合を除く)、タイムゾーンを設定するだけで、他の調整は行われません。

(ナイーブな日時ではなく)UTCで内部的に作業しreplace、ローカライズされた方法で日時のI / Oを実行する必要がある場合に使用できます(normalizeDSTなどを処理します)。

于 2009-09-04T15:12:52.100 に答える
25

localizeは、初期の固定日時値を使用して日時対応オブジェクトを作成するために使用する正しい関数です。結果の日時認識オブジェクトは、元の日時値を持ちます。私の見解では非常に一般的な使用パターンであり、おそらくpytzがより適切に文書化できるパターンです。

replace(tzinfo = ...)残念ながら名前が付けられています。これは、動作がランダムな関数です。自傷行為を楽しんでいない限り、この関数を使用してタイムゾーンを設定することは避けてください。私はすでにこの関数を使用することに十分苦しんでいます。

于 2017-03-30T20:30:24.760 に答える
11

このDstTzInfoクラスは、UTCからのオフセットが特定の時点で変化するタイムゾーンに使用されます。たとえば(おそらくご存知のとおり)、多くの場所は夏の初めに「夏時間」に移行し、夏の終わりに「標準時間」に戻ります。各DstTzInfoインスタンスは、これらのタイムゾーンの1つのみを表しますが、「localize」および「normalize」メソッドは、適切なインスタンスを取得するのに役立ちます。

アビジャンの場合、(pytzによると)移行は1回しかなく、それは1912年のことです。

>>> tz = pytz.timezone('Africa/Abidjan')
>>> tz._utc_transition_times
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)]

pytzから取得するtzオブジェクトは、1912年以前のタイムゾーンを表します。

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>

2つの例を見てみましょう。tz.localize(d)を呼び出すと、この1912より前のタイムゾーンが単純な日時オブジェクトに追加されないことがわかります。指定した日時オブジェクトは、その現地時間の正しいタイムゾーン(1912年以降のタイムゾーン)の現地時間を表すと想定しています。

ただし、d.replace(tzinfo = tz)を使用する2番目の例では、datetimeオブジェクトを使用して1912より前のタイムゾーンの時刻を表します。これはおそらくあなたが意図したことではありません。次に、dt.normalizeを呼び出すと、これがその日時の値に適したタイムゾーン、つまり1912年以降のタイムゾーンに変換されます。

于 2009-10-20T06:40:10.903 に答える
8

私はこれに少し遅れていることに気づきました...しかし、これが私がうまくいくとわかったものです。Alexが述べたようにUTCで作業します。

tz = pytz.timezone('Africa/Abidjan')
now = datetime.datetime.utcnow()

次にローカライズするには:

tzoffset = tz.utcoffset(now)
mynow = now+tzoffset

そして、このメソッドはDSTを完全に処理します

于 2011-01-14T17:23:16.093 に答える