概要

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)
)

 

おしまい

こういうトピック、結構好きだ。ツールボックスの中の道具を、少し砥ぐような気持ちよさがある。