class Permit(models.Model): ... expires = models.DateTimeField() created = models.DateTimeField(auto_now_add=True)
... permit = Permit.object.get(id=xxx) if permit.expires < datetime.now(): # ERROR ...naiveとawareの意味が判らないので、まずは、そこから調査。
Pythonの日付処理とTimeZoneによると、TimeZone情報を持ったdatetimeオブジェクトがaware, 持たない場合がnaive。awareとnaiveで比較するとエラーになることが判明。
次にDjangoだが、settings.pyにTimeZoneの有効/無効の設定があり、デフォルトは有効になっている
... # If you set this to False, Django will not use timezone-aware datetimes. USE_TZ = True ...
では、実際に、それぞれのFieldにどんな値が設定されているのか確認すると expiresは日本時間がUTCとして、createdは正しい現在時刻がUTCとして設定されていた。
そこで、以下の2ヶ所を修正をして、期待通りの動作になった。
まず、expiresに値を設定するところでTimeZoneを指定するようにした。
class Permit(models.Model): ... def save(self, *args, **kwargs): dt = datetime.strptime(xxx) self.expires = dt.replace(tzinfo=pytz.timezone('Asia/Tokyo')) ...
次に時間を比較するところで、UTCを使用するように変更
import pytz ... permit = Permit.objects.get(id=xxx) if permit.expires < datetime.utcnow().replace(tzinfo=pytz.UTC): ...
もっと、よく調べたら、Djangoに便利なユーティリティーが存在することが判明
from django.utils import timezone ... permit = Permit.objects.get(id=xxx) if permit.expires < timezone.now(): ...