こんにちは。 ディベロップメントサービス1課の山本です。
今回は datetime 型にて、タイムゾーンを扱う場合の注意点を説明します。
タイムゾーンの変更方法は主に 2 種類あり、それぞれ挙動が異なるため解説します。
この記事の対象者は?
- タイムゾーンを持つ時間を扱っている方
datetime 型 のタイムゾーンについて
datetime 型 には 時刻のタイムゾーンを指定することができます。
タイムゾーンの指定有無によって、aware
と naive
に分類されます。
- aware オブジェクト:タイムゾーン有り
- naive オブジェクト:タイムゾーン無し
datetime --- 基本的な日付と時間の型 — Python 3.12.5 ドキュメント
コード
import datetime as dt tz_info_utc = zoneinfo.ZoneInfo("UTC") def main(): dt_now_naive = dt.datetime.now() dt_now_aware_utc = dt.datetime.now(tz_info_utc) print(f"dt_now_naive: {dt_now_naive}") print(f"dt_now_aware_utc: {dt_now_aware_utc}") if __name__ == '__main__': main()
出力結果
dt_now_naive: 2024-08-28 17:06:35.415768 dt_now_aware_utc: 2024-08-28 08:06:35.415770+00:00
末尾のタイムゾーンによる時差の有無で確認できます。
datetime.now()
にて 生成した場合は
ローカルのシステム設定を参照して時刻を取得します。(今回の場合は JST )
タイムゾーンの変更方法
タイムゾーンの変更方法は主に、以下の2つがあります。
- datetime.replace()
- 時刻の調整は実施せずに、タイムゾーンのみを変更する
- datetime.astimezone()
- 時刻の調整とタイムゾーンを変更する。
少し説明が難しいので、表にして整理してみます。
ローカルタイムゾーン が UTC システム上で変換する前提です。
変換元 | replace(JST) | astimezone(JST) |
---|---|---|
2024-01-01 12:00:00 | 2024-01-01 12:00:00+09:00 | 2024-01-01 21:00:00+09:00 ※ |
2024-01-01 12:00:00+03:00 | 2024-01-01 12:00:00+09:00 | 2024-01-01 18:00:00+09:00 |
※ naive オブジェクトの場合は、ローカルタイムゾーン を参照して時刻を調整する。
https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.replace https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.astimezone
まとめ
- datetime.replace() はタイムゾーンを変更するだけ。時刻は変えない。
- datetime.astimezone() は変更前後のタイムゾーンに応じて、時刻も変える。
余談
ユニットテストでよく利用される freezegun にて tz_offset
の指定無しで時刻を固定すると、ローカルのタイムゾーンは "UTC" となります。
コード
import zoneinfo import datetime as dt import freezegun tz_info_utc = zoneinfo.ZoneInfo("UTC") @freezegun.freeze_time("2021-01-01") def main(): dt_now_naive = dt.datetime.now() dt_now_aware_utc = dt.datetime.now(tz_info_utc) print(f"now_naive: {dt_now_naive}") print(f"now_aware_utc: {dt_now_aware_utc}") if __name__ == '__main__': main()
出力結果
now_naive: 2021-01-01 00:00:00 now_aware_utc: 2021-01-01 00:00:00+00:00
さいごに
テスト結果が期待値と 9 時間ずれて悩んだ末、これに気づきました。。。
本ブログがどなかたのお役に立てれば幸いです。