Django 1.4のタイムゾーン

Django 1.4からDateTimeFieldのタイムゾーンの扱いが変更されている
https://docs.djangoproject.com/en/dev/releases/1.4/#support-for-time-zones

いくつか警告やエラーに遭遇したので、気がついた挙動をまとめてみる

動かした環境は OSX 10.7.5、Python 2.7.2、Django 1.4.1、MySQL 5.5、MySQL-python 1.2.3

from django.conf import settings
import pytz


print settings.TIME_ZONE
#=> Asia/Tokyo


# datetime.nowで取得される日時はsettings.pyのTIME_ZONEの時間が取得されるが、datetimeオブジェクトはtzinfoは保持していない
now = datetime.now()
print now
# => 2012-11-23 21:05:02.671992


# DateTimeFieldにtimezoneが特定されていないdatetimeのオブジェクトを渡すとwarningがでる
Book.objects.create(price=100, published=now)
# RuntimeWarning: DateTimeField received a naive datetime (2012-11-23 21:05:02.671992) while time zone support is active.


# 保存されたオブジェクトを取り出すとDateTimeFieldのtzinfoはUTCになっている
b = Book.objects.all()[0]
print b.published
# => 2012-11-23 12:05:02+00:00


# astimezoneでtimezoneを変換できる
print b.published.astimezone(pytz.timezone('Asia/Tokyo'))
# => 2012-11-23 21:05:02+09:00


# timezoneを保持しているdatetimeと保持していないdatetimeを比較するとエラーになる
b.published > datetime.utcnow()
# => TypeError: can't compare offset-naive and offset-aware datetimes


# timezoneを指定したdatetimeで比較する
b.published > datetime.utcnow().replace(tzinfo=pytz.utc)
# もしくは
b.published > datetime.now(pytz.utc)