1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonでastimezoneを使う前に必ず知っておいてほしいこと

1
Last updated at Posted at 2026-03-02

qiita技術ブログ (34).png

はじめに

日時情報を扱う中で、タイムゾーンを持たない日時データ(naive)タイムゾーン付きの日時データ(aware)に変換する場面は少なくありません。

本記事では、その際にastimezone()を使用するときの注意点についてまとめました。

結論を最初に述べると、タイムゾーンを持たない日時オブジェクトに対してastimezone()を使用すると、実行環境によって時刻ズレが発生してしまうため、単にタイムゾーン情報を付与したい場合はreplace()を使おうという話です。

この記事では、

  • なぜ時刻ズレが発生するのか
  • どう実装すべきか

を、実装例を挙げて説明します。

前提知識: naiveとawareとは

datetimeオブジェクトは、タイムゾーン情報を含むかどうかによってnaiveawareの2種類に分類されます。

  • naive object: タイムゾーン情報を持たないオブジェクト
  • aware object: タイムゾーン情報を持つオブジェクト

問題が起きるコード

例えば次のタイムゾーン時間を持たない文字列の日時データを扱うケースを考えます。

2026-03-03 12:00:00

この値を日本時間の2026-03-03 12:00として扱うために、以下の問題があるサンプルコードを用意しました。

from datetime import datetime
from zoneinfo import ZoneInfo

JST = ZoneInfo("Asia/Tokyo")

dt = datetime.strptime("2026-03-03 12:00:00", "%Y-%m-%d %H:%M:%S")
astimezone_result = dt.astimezone(tz=JST)
print(f"出力結果: {astimezone_result.isoformat()}")

実際に実行してみる

ローカルで実行した場合

ローカルのastimezone実行結果.png

ローカルでは問題無く日本時間の2026-03-03 12:00になっていますね。

サーバー環境(例:AWS Lambda)上で実行した場合

実装コード

Lambdaでのastimezoneサンプルコード.png

出力結果

Lambdaでのastimezone実行結果.png

9時間ずれて2026-03-03 21:00になってしまっていますね。

なぜastimezone()だとズレるのか

astimezone()の処理として、naiveのオブジェクトをローカルタイムとして解釈してから指定されたタイムゾーンに変換されます。

そのため、多くのサーバー環境(例: AWS Lambda)はローカルタイムがUTCのため、内部的に次のように解釈され変換後に時間がズレるというわけです。

12:00(ローカルタイムからUTCとして解釈)
        ↓
21:00(+9時間をしてUTCからJSTに変換)

正しい実装例

naiveなdatetimeにJSTのタイムゾーン情報を付与する方法の例としてreplaceメソッドがあります。

今回の問題のあるコードを以下のようにreplaceメソッドで日本時間のタイムゾーンを持たせるようにしました。

from datetime import datetime
from zoneinfo import ZoneInfo

JST = ZoneInfo("Asia/Tokyo")

dt = datetime.strptime("2026-03-03 12:00:00", "%Y-%m-%d %H:%M:%S")
replace_result = dt.replace(tzinfo=JST)
print(f"出力結果: {replace_result.isoformat()}")

実際に実行してみる

Lambdaでのreplace実行結果.png

replaceだと無事時間がズレることなくJSTのタイムゾーン情報を付与することができました!

公式ドキュメント参考
Python公式ドキュメントのdatetime.astimezoneの説明にも以下のように日時を変更せずに単にタイムゾーンを付与したい場合はreplace(tzinfo=tz)を使用するよう明記されています。

If you merely want to attach a timezone object tz to a datetime dt without adjustment of date and time data, use dt.replace(tzinfo=tz).

まとめ

本記事では、私自身がastimezone()を使用した際に想定外の挙動に遭遇した経験をもとに、naiveawareの違いおよびastimezone()の仕様について整理しました。
同様の実装をされている方、これから実装を予定している方の参考になれば幸いです。

最後までお読みいただきありがとうございました。

参考

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?