日付処理

[Python] datetimeでタイムゾーンを扱う方法と注意点

今回は、Pythonのdatetimeでタイムゾーンを扱う方法と注意点についてご紹介します。

タイムゾーンの基本概念

Pythonのdatetimeオブジェクトには、大きく分けてnaive(タイムゾーン情報なし)とaware(タイムゾーン情報あり)の2種類があります。

naiveなdatetimeは、どの地域の時刻なのかを明確に示しません。

awareなdatetimeは、tzinfoを保持しており、地域やUTCとの相対位置などタイムゾーン情報を扱えます。

タイムゾーンを適切に扱うためには、awareなdatetimeを使用し、必要に応じてタイムゾーン間の変換を行うことが重要です。

タイムゾーン付きdatetimeの作り方

Pythonでタイムゾーン付きのdatetimeを生成する方法はいくつかあります。

ここでは、datetime.timezonezoneinfo(Python 3.9以降)、そしてサードパーティライブラリのpytzの3つを紹介します。

datetime.timezoneを使う方法

Python 3.2以降では、datetime.timezoneを使用して固定オフセットのタイムゾーンを扱えます。

以下はUTC+9(日本標準時:JST)のオフセットを指定する例です。

実行結果

JST: 2023-05-17 12:00:00+09:00
UTC: 2023-05-17 03:00:00+00:00

この方法は固定オフセットであれば簡単に扱えますが、DST(夏時間)の切り替えなどは考慮されません。

zoneinfoを使う方法

Python 3.9以降では、zoneinfoモジュールが標準ライブラリに追加されました。

IANAタイムゾーンデータベースに基づく地域ごとのタイムゾーンを指定でき、DSTなどの自動調整も行われます。

実行結果

Tokyo: 2023-05-17 12:00:00+09:00
UTC: 2023-05-17 03:00:00+00:00

zoneinfoモジュールを使うと、地域独自の夏時間対応や歴史的なタイムゾーン変更にも対応できます。

pytzを使う方法

Pythonで長年用いられてきたライブラリとして、pytzがあります。

pytzを使用する場合、tzinfoを直接指定するのではなく、localize()を使ってnaiveなdatetimeをawareなdatetimeへ変換する点に注意が必要です。

実行結果

Tokyo (pytz): 2023-05-17 12:00:00+09:00
UTC (pytz): 2023-05-17 03:00:00+00:00

現在は標準ライブラリのzoneinfoが推奨される傾向にありますが、既存のコード資産などの理由でpytzを使うケースも依然として残っています。

タイムゾーン対応で注意すべきポイント

タイムゾーンを正しく扱う上では、以下の点に注意する必要があります。

  • naiveなdatetimeとawareなdatetimeの混在
  • DST(夏時間)や歴史的なタイムゾーンの変更
  • 関数のデフォルト動作(datetime.now()はnaiveなdatetimeを返すなど)
  • サードパーティライブラリ固有の使い方(pytzはlocalize()が必須)

特にnaiveとawareの比較や演算をそのまま行うとTypeErrorを引き起こすため、常にどちらかに統一するか、変換してから操作することが大切です。

DSTの切り替えが存在する地域を扱う場合は、切り替え時期に同じローカル時刻が重複したり、存在しなかったりするため、コードを書いた後で実際の動作をしっかり確認することが望ましいです。

datetime.timezoneは固定オフセットしか扱えないため、DST対応が必要な場合はzoneinfoやpytzなどを使うと便利です。

まとめ

Pythonでタイムゾーンを扱う際は、awareなdatetimeオブジェクトを活用することで正確な日時計算が可能になります。

固定オフセットが問題なければdatetime.timezone、DSTを含む複雑な要件がある場合はzoneinfoやpytzを検討すると効率的です。

naiveとawareの区別やDSTの扱いなどを理解し、用途に合わせたタイムゾーン管理を行いましょう。