...
from google.appengine.ext import db
class FooModel(db.Model):
...
...
created = db.DateTimeProperty(auto_now_add=True)
以 DateTimeProperty
來說,它對應到的資料結構是 python 標準函式庫中的 datetime.datetime
,不過,當你加上了 auto_now_add=True
這個設定之後,每當建立一個新的 entity 時,Datastore API 就會自動加上「現在時間」,也就是 datetime.datetime.now()
的資料,但是 App Engine 所使用的預設時區是 UTC(也就是 GMT+0),簡單地說,如果你的網站使用者都是台灣的用戶,那就會感覺到這個時間晚了八個小時(因為台灣的時區是 CST,也就是 GMT+8),如果要處理這個問題,這裡提供兩個可能的解決方法:不要依賴自動產生的時間,DIY
第一個解決方法,就是在產生/儲存 entity 時不要讓 Datastore API 幫你產生現在的時間,每次在產生或是更新 entity 資料時,自己手動產生出正確的時間。在解決問題之前,首先要製作一個台灣時區的tzinfo
,才可以去改變 datetime.datetime
所表示的時區:...
from datetime import tzinfo, timedelta
class TaiwanTimeZone(tzinfo):
def utcoffset(self, dt):
return timedelta(hours=8)
def tzname(self, dt):
return 'CST'
def dst(self, dt):
return timedelta(hours=0)
接著,在產生或更新 entity 資料時:
...
foo = FooModel(......,
created=datetime.datetime.now(TaiwanZone()))
foo.put()
這樣就會用台灣時區(GMT+8)的時間來儲存資料了。在輸出時用 filter 換掉
另外一個方式,就是在 template 要輸出時再換掉時區,當然還是要準備一個TaiwanTimeZone
的 tzinfo
類別,然而在儲存資料時,還是使用預設的 UTC 時區去處理,但是可以自訂一個 template filter (詳細的作法請見這篇文章)在 template 中顯示時動態換掉時間及時區:# get template register
register = webapp.template.create_template_register()
@register.filter
def twtz(value):
from datetime import datetime, timedelta
return (value + timedelta(hours=8)).replace(tzinfo=TaiwanTimeZone())
這樣只要在 template 中加上這個 filter 來顯示就可以了。