Python datetime型の日時を変更せずにtimezoneをセットする

やったこと

すぐ忘れるので
datetime型の変数にtimezoneをセットする書き方を残しておく
「datetime型の日時を変更せずにtimezoneをセットするパターン」と
「timezoneをセットしてそのtzに合わせた日時に変更するパターン」の2つ

.replace()

「datetime型の日時を変更せずにtimezoneをセットするパターン」です

from dateutil import tz
from datetime import datetime

# ISO形式の文字列をdatetimeに変換する
dt_string = '2023-12-11 16:57:00'
dt = datetime.fromisoformat(dt_string)
print('---- with no timezone info ----')
print(dt)
print(dt.tzinfo)

print('---- replace timezone Asia/Tokyo ----')
dt_tz = dt.replace(tzinfo=tz.gettz("Asia/Tokyo"))
print(dt_tz)
print(dt_tz.tzinfo)
---- with no timezone info ----
2023-12-11 16:57:00
None
---- replace timezone Asia/Tokyo ----
2023-12-11 16:57:00+09:00
tzfile('/usr/share/zoneinfo/Asia/Tokyo')

元の日時2023-12-11 16:57の部分は変更されずに、JSTを表す+09:00を付与されていることが確認できます

.astimezone()

「timezoneをセットしてそのtzに合わせた日時に変更するパターン」です

from dateutil import tz
from datetime import datetime

# ISO形式の文字列(末尾にZ)をdatetimeに変換する
# 末尾にZがある場合はUTCとして扱われる
dt_string_with_tz = '2023-12-11 16:57:00Z'
dt_utc = datetime.fromisoformat(dt_string_with_tz)
print('---- with timezone UTC ----')
print(dt_utc)
print(dt_utc.tzinfo)

# astimezoneを使って、UTCからAsia/Tokyoに変換する
# 日時が変わることに注意(+9時間される)
print('---- as timezone Asia/Tokyo ----')
dt_jst = dt_utc.astimezone(tz.gettz("Asia/Tokyo"))
print(dt_jst)
print(dt_jst.tzinfo)
---- with timezone UTC ----
2023-12-11 16:57:00+00:00
UTC
---- as timezone Asia/Tokyo ----
2023-12-12 01:57:00+09:00
tzfile('/usr/share/zoneinfo/Asia/Tokyo')

replace()を使用した時と違って、2023-12-11 16:57 がプラス9時間され2023-12-12 01:57に変更されています

まとめ

日時を変えたくないけどtzを設定したい場合は.replace()
UTCの時刻をJSTに変換したいなら.astimezeon()