私は何をする必要がありますか
タイムゾーンを認識しない datetime オブジェクトがあり、他のタイムゾーンを認識する datetime オブジェクトと比較できるようにするために、タイムゾーンを追加する必要があります。この1つのレガシーケースを認識しないタイムゾーンにアプリケーション全体を変換したくありません。
私が試したこと
まず、問題を示すために:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> aware == unaware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
まず、私は astimezone を試しました:
>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: astimezone() cannot be applied to a naive datetime
>>>
実際に変換を行おうとしているので、これが失敗したことはそれほど驚くべきことではありません。置換はより良い選択のように思えました ( How do I get a value of datetime.today() in Python that is "timezone aware"?に従って):
>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> unaware == aware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
>>>
しかし、ご覧のとおり、replace は tzinfo を設定しているように見えますが、オブジェクトを認識させていません。解析する前に入力文字列を改ざんしてタイムゾーンを取得する準備をしています (解析に dateutil を使用していますが、それが重要な場合)。
また、Python 2.6 と Python 2.7 の両方でこれを試しましたが、同じ結果が得られました。
環境
いくつかのデータ ファイルのパーサーを作成しています。日付文字列にタイムゾーン インジケーターがない場合、サポートする必要がある古い形式があります。データ ソースは既に修正済みですが、従来のデータ形式をサポートする必要があります。さまざまなビジネス BS の理由から、レガシー データの 1 回限りの変換はオプションではありません。一般に、デフォルトのタイムゾーンをハードコーディングするという考えは好きではありませんが、この場合はそれが最良の選択肢のようです。問題のすべてのレガシー データが UTC であることはかなりの自信を持って知っているので、この場合、それをデフォルトにするリスクを受け入れる準備ができています。