Pythonのdatetime.utcnow()でハマる

Pythonのdatetime.utcnow()のお話


AwareとNaive

PythonのdatetimeモジュールにはAware型とNaive型が存在します(マニュアル)。Aware型はタイムゾーン情報を保持しており、Naive型はタイムゾーン情報を持たないという区分のようです。

はまった点

Naive型はタイムゾーン情報を持ちませんが、それは協定世界時 (UTC)として扱われるという意味ではなく、多くの場合ローカルタイムを前提とした処理が行われます。

ここでdatetime.utcnow()Naive型のUTC時間を返してくれます。これを例えばtimestamp()関数などでUNIX時間 (POSIX time)に変換すると想定外のことが発生します

    print(datetime.now())        # ローカル時間取得
    print(datetime.utcnow())     # UTC時刻を取得
    print("-" * 30)
  # それぞれのUNIX時間を取得
    print(datetime.now().timestamp())
    print(datetime.utcnow().timestamp()))
    print("-" * 30)
2020-05-12 14:24:23.081485
2020-05-12 05:24:23.081485
------------------------------
1589261063.081485
1589228663.081485
------------------------------

上記コードではdatetime.now()datetime.utcnow()でローカル時間、およびUTC時間を取得。timestamp()でUNIX時間に変換すると、Naive型のdatetime.now()はローカル時間として扱われ、同じ時間が取得できると思いきや、実はdatetime.utcnow()もNaive型のため、そこからさらにローカルとUTCとの時差が補正されてしまいます…

公式ドキュメントにも記載されていますが、UTC時刻を取得する場合はdatetime.now(timezone.utc)としてAware型として取得するのがいいようです。(要はちゃんとドキュメント読みましょうってことですね)

(datetime.utcnow()っていつ使うんだろ…)

おすすめ