GAE中使用Google数据API的本地时区问题
我正在开发一个小应用,使用的是Google App Engine(Python),这个应用通过Google数据API来创建一个新的日历,并在里面添加一些事件。
我使用的事件数据是从其他地方解析过来的,这些事件的日期是以欧洲/斯德哥尔摩的时区表示的(我想是夏令时CEST或标准时CET)。
所以,首先我会用Python创建一个时间结构,比如这样:
start = strptime("2009-11-16 10:15", "%Y-%m-%d %H:%M")
Python的文档说我可以用标志%Z来指定时区,实际上在我的Python解释器中是可以用的……但是在Google App Engine服务器上(无论是本地还是部署后)就完全不行了。这并不是新鲜事,我在这里也看到过类似的问题。
因为我在使用Google数据API,而它需要时间以UTC/GMT格式,所以我需要一种方法将欧洲/斯德哥尔摩的本地时间转换为UTC/GMT,而不使用strptime中的%Z标志……(而且我希望这个方法比单纯地每个日期减去一个小时要聪明一些……)
再次感谢你们的帮助 :)
2 个回答
在把你的对象转换成日期时间格式之后,你需要添加时区。为此,你需要创建一个从datetime.tzinfo类派生的类。
import datetime as dt class SomeZone(dt.tzinfo): # a helper class to quickly create simple timezones - give gmt_offset def __init__(self, gmt_offset): dt.tzinfo.__init__(self) self.gmt_offset = gmt_offset def utcoffset(self, dtime): return dt.timedelta(hours=self.gmt_offset) def dst(self, dtime): return dt.timedelta(0) def tzname(self, dtime): return None start = strptime("2009-11-16 10:15", "%Y-%m-%d %H:%M") start.replace(tzinfo=SomeZone(your_offset_here))
好了,现在它就是一个带有时区的日期时间了。从这里开始,谷歌会接手,因为日期时间字段会考虑时区,并且在存储时会以UTC格式保存。
只要记得夏令时和其他相关的事情就可以了。
如果你想深入了解,我在上面提到的类可以在这里找到。
我去年在我的博客上发过一篇关于这个主题的文章,里面提到了一些相关内容。简单来说,就是在存储时间的时候,所有的时间都会转换成UTC(协调世界时),然后在读取的时候再加上UTC的时区。你可以随意修改这个方法,把时间转换成你想要的任何本地时区。
这个代码示例可能有点过时了,因为我很久没用过appengine了。不过我希望它能在某种程度上对你有所帮助。
import pytz
class TzDateTimeProperty(db.DateTimeProperty):
def get_value_for_datastore(self, model_instance):
if model_instance.posted_at.tzinfo is None:
model_instance.posted_at = model_instance.posted_at.replace(tzinfo=pytz.utc)
else:
model_instance.posted_at = model_instance.posted_at.astimezone(pytz.utc)
return super(TzDateTimeProperty, self).get_value_for_datastore(model_instance)
def make_value_from_datastore(self, value):
value = super(TzDateTimeProperty, self).make_value_from_datastore(value)
if value.tzinfo is None:
value = value.replace(tzinfo=pytz.utc)
else:
value = value.astimezone(pytz.utc)
return value
我还推荐一个很棒的库叫pytz;它提供了几乎所有有用的时区对象。(我想给它链接,但防止垃圾信息的机制阻止了我。你可以在网上搜索一下。)