概要
Python 3 では、 pytz
ではなく datetime.timezone
を使うこと。
“でーたべーすには UTC 時刻を保存しておいて、使うときに localize する” という手法が緑さんの中で定着してきて久しい。 Datetime オブジェクトに timezone を付与するときにはサードパーティの pytz モジュールを使ってきた。
のだけど、最近、 Python 3 では timezone は組み込みモジュール datetime だけで実現できることを知った。なるべくサードパーティ製モジュールは少なく、組み込みモジュールだけで Python を書きたいところであるので、そのやり方をおさえようぜ。
てか pytz は Python 2 で timezone を使うための方法であり、遅いし、 Python 3 では不要。全然知らなかった。 Python 3 を使い始めて5年以上経つというのに……!
事前知識 aware と naive
- Timezone 情報を持っている datetime を aware という。
- Timezone 情報を持たない datetime を naive という。英語で naive は "考えが甘い" という意味。覚えやすいね。
これまで pytz でこう書いていたところは……
pip install pytz
import datetime
import pytz
TZ_UTC = pytz.utc
TZ_JST = pytz.timezone('Asia/Tokyo')
# 今の UTC 時刻。
print(datetime.datetime.now(tz=TZ_UTC))
# 今の JST 時刻。
print(datetime.datetime.now(tz=TZ_JST))
# 特定の時刻の UTC。
print(datetime.datetime(2022, 2, 7, tzinfo=TZ_UTC))
# 特定の時刻の JST。
print(datetime.datetime(2022, 2, 7, tzinfo=TZ_JST))
# UTC -> JST 変換。
print(
TZ_JST.normalize(datetime.datetime.now(tz=TZ_UTC))
)
datetime.timezone を使ってこう書き直そう
import datetime
TZ_UTC = datetime.timezone.utc
TZ_JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')
# 今の UTC 時刻。 (ここは同じ)
print(datetime.datetime.now(TZ_UTC))
# 今の JST 時刻。 (ここは同じ)
print(datetime.datetime.now(TZ_JST))
# 特定の時刻の UTC。 (ここは同じ)
print(datetime.datetime(2022, 2, 7, tzinfo=TZ_UTC))
# 特定の時刻の JST。 (ここは同じ)
print(datetime.datetime(2022, 2, 7, tzinfo=TZ_JST))
# UTC -> JST 変換。
print(
datetime.datetime.now(TZ_UTC).astimezone(tzinfo=TZ_JST)
)
おしまい
こういうトピック、結構好きだ。ツールボックスの中の道具を、少し砥ぐような気持ちよさがある。