ちょっとはまったのでメモしておきます。
環境
- python 3.8.10
navive と aware
まず、datetime
型にはタイムゾーンの情報を持たない naive
と、タイムゾーンの情報を持つ aware
な datetime 型があるようです。
naive な datetime 型
from datetime import datetime, date, timedelta, timezone
dt = datetime.now()
print(dt.isoformat())
出力結果
2021-09-13T15:11:50.968159
aware な datetime 型
from datetime import datetime, date, timedelta, timezone
JST = timezone(timedelta(hours=+9), 'JST')
dt = datetime.now(JST)
print(dt.isoformat())
出力結果
datetime.now
で JST
を指定しているので、文字列で出力したときに +09:00
が付与されています。
2021-09-13T15:12:28.720290+09:00
文字列から datetime への変換
str = '2021-09-13T15:11:50.968159'
dt = datetime.fromisoformat(str)
print(dt)
str = '2021-09-13T15:12:28.720290+09:00'
dt = datetime.fromisoformat(str)
print(dt)
出力結果
文字列にタイムゾーンに関する情報がなければ naive
、あれば aware
な datetime
型になっていることがわかります。
2021-09-13 15:11:50.968159
2021-09-13 15:12:28.720290+09:00
naive から aware への変換
naive
に対して astimezone
でタイムゾーンの情報を付与すると aware
になります。
str = '2021-09-13T15:11:50.968159'
dt = datetime.fromisoformat(str) # naive
print(dt)
jst_dt = dt.replace(tzinfo=timezone.utc) # aware
print(jst_dt)
2021-09-13 15:11:50.968159
2021-09-13 15:11:50.968159+00:00
UTC から JST への変換
str = '2021-09-13T15:11:50.968159'
# タイムゾーンの情報がないので、naive な datetime になる
dt = datetime.fromisoformat(str) # naive
print(dt)
# 上記の dt は UTC として解釈する(タイムゾーンを付与する)
utc = dt.replace(tzinfo=timezone.utc) # aware(UTC)
print(utc)
# JST に変換する
jst = utc.astimezone(JST) # aware(JST)
print(jst)
出力結果
2021-09-13 15:11:50.968159
2021-09-13 15:11:50.968159+00:00
2021-09-14 00:11:50.968159+09:00
タイムゾーンのない文字列を JST として読み込む
上記の応用で、最初から JST を指定してやると OK です。
str = '2021-09-13T15:11:50.968159'
# タイムゾーンの情報がないので、naive な datetime になる
dt = datetime.fromisoformat(str) # naive
print(dt)
# 上記の dt は JST として解釈する(タイムゾーンを付与する)
JST = timezone(timedelta(hours=+9), 'JST')
jst = dt.replace(tzinfo=JST) # aware(JST)
print(jst)
出力結果
2021-09-13 15:11:50.968159
2021-09-13 15:11:50.968159+09:00