根據數據存儲區docs,日期時間始終以UTC存儲和返回。強制Google雲的數據存儲區日期時間默認爲UTC
但是,在雲儀表板中,我所有的日期時間都顯示在CEST
中,即UTC+2
。
保存實體時,我不包含任何時區並使用datetime.utcnow()
。
更具體地講,這是我TimeZonedDateTimeProperty
模型,擴展/部分壓倒一切的谷歌自己的db.DateTimeProperty
:
class TimeZonedDateTimeProperty(db.DateTimeProperty):
def __init__(self, *args, **kwargs):
super(TimeZonedDateTimeProperty, self).__init__(*args, **kwargs)
def __get__(self, model_instance, model_class):
"""Returns the value for this property on the given model instance."""
if model_instance is None:
return self
attr_to_return = None
try:
# access the db.DateTimeProperty's getter
attr_to_return = getattr(model_instance, super(TimeZonedDateTimeProperty, self)._attr_name())
except AttributeError:
attr_to_return = None
if attr_to_return:
# super methods of db.DateTimeProperty will be calling this
# getter too and we don't wanna mess up
# the UTC convention when working with datetimes
includes_correct_caller = None
try:
# after noticing that this getter is also being called
# outside of user requests, inspect the caller and decide
# whether to offset the UTC datetime or not
includes_correct_caller = "main_class_name" in str(inspect.stack()[1][0].f_locals["self"].__class__)
except Exception:
includes_correct_caller = False
if includes_correct_caller:
return attr_to_return + relativedelta(hours=+2)
else:
return attr_to_return
else:
return None
而這裏的一個子類db.Model
用法的例子:
class Message(db.Model):
...
sent = TimeZonedDateTimeProperty()
...
m = Message(...
sent=datetime.utcnow(),
...)
m.put()
現在,如果我打電話在本地主機上運行的m.sent
,事情按計劃進行,即sent
屬性以UTC保存,並且getter返回偏移日期時間。
在現場/生產環境中,屬性爲而不是以UTC保存,因此重寫的獲取器不必要地增加2個小時。
所以:
我怎樣才能迫使現場數據存儲始終使用UTC保存和服務我的日期時間是什麼時候?
我的方法是否正確?假設它是,是否有一種更優雅的方式來處理GAE中的分時日期?
謝謝!
關於雲儀表板,我認爲這只是一個代表性的問題。我們有(ndb)使用'ndb.DateTimeProperty(auto_add = True)'記錄時間戳記的模型;在雲儀表板中,時間戳顯示爲本地時間:2017-06-10(21:36:07.917)BST,但是如果我在遠程shell中打印時間戳,則時間與UTC相當:2017-06-10 20: 36:07.917540。 – snakecharmerb
相關:https://stackoverflow.com/questions/29949938/why-do-datastore-datetimes-look-different-in-appengine-console-vs-appengine-dash –
好的,儀表板的表示是可以理解的。 但它仍然好像我的getter被調用了put()或put_async() - 雖然我有一種預感,但這不是標準做法。但是對於重複+ 2小時的添加幾乎沒有任何解釋。 –