系統:
python 2.7.12Django 1.8.17
OS: linux mint 18.1 Serena
起始:
一開始因為有個model裡面有個欄位是放expire time,用來辨別這個東西是否過期。所以很直覺的就會用datetime來做比對。例如:
from clover.models import food import datetime apple = food.objects.get(name='apple') print(datetime.datetime.now() > apple.expire_time)
這邊只是很單純比較apple 是否過期,也就是說當現在的日期 大於 apple的過期日~就會印出True, 否就印出False !在命令列去執行時會出現錯誤如下:
出現 TypeError: can't compare offset-naive and offset-aware datetimes 錯誤!
於是乎開始去了解這是什麼問題。
原因:
後來參考了Django 官方網站與Stackoverfollow才又得知一件之前不知道的事情。由於Django是採用UTC的時區儲存Database有關datetime的資訊,並且是採用time-zone-aware的datetime objects作為內部使用,而且透過轉換這些物件應用在templates與form表單的當前使用者。
再來是關於 offset-naive 與 offset-aware 的意義。依照Django 官方的說明是指:
如果這個datetime object擁有tzinfo的屬性並且可以儲存 time zone的資訊就稱作aware,
反之為naive。
這時候我們可使用Django 內建的is_aware() 與is_naive()做測試。
from django.utils import timezone import datetime timezone.is_aware(datetime.datetime.now()) <= False
解決方式:
簡單的作法是採用Django內建timezone來使用。例如:
from django.utils import timezone from clover.models import food import datetime apple = food.objects.get(name='apple') print(timezone.now() > apple.expire_time) <= 不會有錯誤訊息
另外還可以搭配原本系統的datetime.timedelta 來做時間的位移。
例如:
from django.utils import timezon import datetime after_a_day = timezone.now()+ datetime.timedelta(days=1) print(after_a_day) <= 印出一天後的時間 timezone.is_aware(after_a_day) <= True
Reference:
作者已經移除這則留言。
回覆刪除sqlite3 是直接用 pytz 沒錯,但 MySQL 要先執行這行來匯入時區資訊 (django queryset 裡有提到這個): mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
回覆刪除https://dev.mysql.com/doc/refman/5.7/en/mysql-tzinfo-to-sql.html