見出し画像

Django のタイムゾーン処理

[はじめに]

Django のタイムゾーン処理は通常意識しなくて良いが、datetime 値から取り出した値を UI <> コードで受け渡すときには注意が必要というお話。

[詳細]

USE_TZ = True としておけば、Django の datetime 値は aware (UTC) になっており、適切な変換が自動的に施される。

通常はこの値 (UTC) を使って計算したり、DBに保存する事によって、タイムゾーンに左右されない処理を行う事ができる。コード内では、基本的に UTC のまま処理すれば良い。

また、aware な値はタイムゾーンによる変換が可能なので、Django は、テンプレート内で時刻処理を行う際には UI 部分ではローカルタイムを使い、取得する値は UTC となるように自動的に処理してくれる。

つまり、datetime 値の UI (ローカルタイム) <> コード (UTC) 変換は、Django が自動的に行ってくれるので、datetime のまま使う場合には特に意識しなくても良い。

ただし、コード内で年月、時間等を切り出してその値をテンプレートで使う場合には、それらはただの数値なので、当然に変換は働かない。そのため、適切な変換をする必要がある。

[例]

例えば、日本時間 2018年1月1日 7:00 の時に下記の year, month, day, hour をテンプレートに渡せば、year: 2017、month: 12、day: 31、hour:  22 になってしまう。(UTC は、日本時間より 9時間遅れているため)

now = timezone.now()
year = now.year
month = now.month
day = now.day
hour = now.hour

この場合、意図したようにテンプレートに year: 2018、month: 1、day: 1、hour: 7 を渡すには timezone.localtime() を使う。

now = timezone.localtime(timezone.now())
year = now.year
month = now.month
day = now.day
hour = now.hour

Note やるからには、サポートがいただけるような役立つ記事を書きたいものです。サポートは資料購入に宛てます。