Djangoのタイムゾーンサポートについて調べた

公開日: : 最終更新日:2013/08/06 Python ,


Djangoの1.4以降で追加されたタイムゾーンサポートのことがよくわかってなかったのでドキュメントを読みつつ軽くまとめてみました。
Time zones | Django documentation | Django

タイムゾーンサポートの有効化

settings.pyのUSE_TZにTrue/Falseで設定する。
デフォルトでは有効。

概要

タイムゾーンサポートが有効化されていると、日付時刻はデータベースにUTCで保存される。
その際にはDjangoは内部的にtime-zone-awareなdatetimeオブジェクトを使い、テンプレート等で表示するときにユーザーのタイムゾーンに直される。
複数タイムゾーンのユーザーに時刻を表示するときやサマータイム(Daylight Saving Time)対応等で便利。

naiveとaware

Pythonのdatetime.datetimeはnaive(タイムゾーン情報を持っていない)とaware(タイムゾーン情報を持っている)の2種類に区別される。
詳細はPythonのドキュメントより

time や datetime 型のオブジェクト d は naive にも aware にもできます。 d は d.tzinfo が None でなく、かつ d.tzinfo.utcoffset(d) が None を返さない場合に aware となります。 d.tzinfo が None の場合や、 d.tzinfo は None ではないが d.tzinfo.utcoffset(d) が None を返す場合には、 d は naive となります。

8.1. datetime — 基本的な日付型および時間型 — Python 2.7ja1 documentation

tzinfoはタイムゾーンや夏時間の計算に使われる、datetime.tzinfoクラスのサブクラスのインスタンス。

DBレイヤーがnaive datetimeを受け取ると、default time zone(settingsのTIME_ZONE)に従ってUTCに変換しようとする。しかしサマータイムによる曖昧さなどの理由により例外を投げたり不正確な結果になったりするのでnaive datetimeを使うのは良くない。

UTCを扱う

開発者は常にUTCのaware datetimeを扱うべき。
現在時刻を取得するときにはdatetime.datetime.now()ではなくdjango.utils.timezone.now()を使用する。(USE_TZの設定によって適切なdatetimeを返してくれる)

default time zoneとcurrent time zone

default time zone: settingsのTIME_ZONEで指定されたタイムゾーン
current time zone: 表示に使われるタイムゾーン
current time zoneがセットされていない場合はdefault time zoneが表示につかわれる。
djangoがユーザーから自動的に判定してcurrent time zoneを設定したりはしないので、ユーザーのタイムゾーンに合わせて表示するにはdjango.utils.timezone.activate(timezone)によってcurrent time zoneをセットする必要がある。
ドキュメントのこの辺りにタイムゾーン設定のサンプルコードがある。)

pytz

Djangoはpytzがインストールされている場合pytzを利用するため、インストールすることが強く推奨されている。

Fixturesにおけるdatetime

aware(UTCオフセットを含んでいる)

naive

formでのdatetime

Djangoが入力をawareなdatetimeに変換してcleaned_dataに入れてくれたりする。

テンプレートでのdatetime

タイムゾーンに関するタグやフィルタが色々ある。

——–
サマータイムのない日本人にはサマータイム問題ってあんまり実感わかないですね。。
必要ないなら使わないほうがシンプルな気もするけどせっかくだから使えるようになっておきたい。

関連記事

no image

Djangoでreverse後のURLにスクリプト名が入ってしまう

レンタルサーバー上にCGIとしてDjangoを動かそうとしていて、このチケットのdjango.cgi

記事を読む

no image

Django 1.7の新機能Migrations

Django 1.6まででは作成後のモデルに変更を加える場合、手動でSQLを発行するかsouthのよ

記事を読む

no image

PySideインストール後にImportError

QtのPythonバインディングにはPyQtとPySideがあって、元々あったのはGPLのPyQtだ

記事を読む

no image

Django 1.5でDEBUG=Falseにしたら動かないとかstaticが出ないとか

Django 1.5でプロジェクト作って少しして試しにDEBUG=Falseにしてみたら「Serve

記事を読む

no image

Python、DjangoでTwitter認証(Sign in with Twitter)するサンプル

トップページから認証リンクを押すとサインインを求められ、ユーザーのアクセストークンをDBに保存して何

記事を読む

no image

pipでThe C extension could not be compiledとかいうWARNING

CentOS 6.5にpipでpython-twitterを入れようとしたら、依存パッケージのsim

記事を読む

no image

PythonでC++のstd::mapみたいな挙動が欲しい

最近競技プログラミングの問題をちょろちょろやってて、それでC++を使ってるんですが、C++のstd:

記事を読む

no image

python-twitterで複数media(画像)を扱う

現時点で、python-twitterをpipで入れると2.0が入りますが、extended ent

記事を読む

no image

Djangoのカスタムコマンドをコード内から呼ぶ

ドキュメントにまんま書いてあるけど一応メモ。 カスタムコマンド内から他のコマンドを呼び出したい

記事を読む

no image

DjangoでMySQLに絵文字を保存

Twitter関連のプログラムを書いていたのですが、絵文字を含むツイートをDBに保存しようとするとエ

記事を読む

no image
PythonでC++のstd::mapみたいな挙動が欲しい

最近競技プログラミングの問題をちょろちょろやってて、それでC++を使っ

no image
ファイルパーミッションを664から644に変えてもGitで反映されない

って思ったらGitのこと勘違いしてたっていうメモ。 Gitはファイル

no image
CentOS6.9を7.3にアップグレード

CentOS6系から7系へのアップグレードはアップグレードツールが存在

no image
ブラウザにフォームの値を覚えさせない

formのinputやselectにvalueやselectedで現在

no image
[WordPress]dbDelta()でテーブルが作成できない

WordPressのプラグインの勉強をしていて、テーブルを作成するため

→もっと見る

PAGE TOP ↑