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():
...
0 件のコメント:
コメントを投稿