【问题标题】:Why doesn't appengine auto-convert datetime to UTC when calling put()为什么调用 put() 时 appengine 不自动将日期时间转换为 UTC
【发布时间】:2012-09-27 15:41:32
【问题描述】:

这就是我想要做的:用户提交太平洋时间,提交后我使用 .replace 将时区设置为太平洋。

Pacific = time.USTimeZone(-8, "Pacific",  "PST", "PDT")
addEvent.date = addEvent.date.replace(tzinfo=Pacific)

一旦我设置了 tzinfo,我正在做一个 put。根据 google appengine 的 python 文档,它说:

"如果 datetime 值具有 tzinfo 属性,则将其转换为 UTC 时区进行存储。值从数据存储区返回为 UTC,tzinfo 为 None。需要日期和时间值的应用程序在特定时区更新值时必须正确设置tzinfo,访问值时将值转换为时区。”

但是,当我执行 put() 时,我收到以下错误:

警告 2012-10-06 21:10:14,579 tasklets.py:399] 初始生成器 _put_tasklet(context.py:264) 引发 NotImplementedError(DatetimeProperty 日期只能支持 UTC。请派生一个新属性以支持替代时区。 ) 警告 2012-10-06 21:10:14,579 tasklets.py:399] 暂停生成器 put(context.py:703) 引发 NotImplementedError(DatetimeProperty 日期只能支持 UTC。请派生一个新属性以支持替代时区。)

请注意我正在使用 NDB

好的,所以在这样做之后,我假设 NDB 可能不会自动将其转换为 UTC。因此,我尝试使用以下代码将其转换为 UTC:

class UTC(tzinfo):
  def utcoffset(self, dt):
    return timedelta(0)
  def tzname(self, dt):
    return str("UTC")
  def dst(self, dt):
    return timedelta(0)

现在即使将太平洋时间转换为 UTC 并将 tzinfo 名称设置为“UTC”,我仍然会遇到相同的错误。

真的可以在这里使用大量的帮助... 谢谢!

【问题讨论】:

    标签: google-app-engine app-engine-ndb


    【解决方案1】:

    解决办法是把tzinfo从转换为UTC后的时间里彻底去掉。

    timestamp = timestamp.replace(tzinfo=None)
    

    【讨论】:

    • 实际上一个例子会很有帮助。
    • 这里是一个示例:在将属性设置为时间戳之前执行 timestamp = timestamp.replace(tzinfo=None)。
    • 这不是简单地删除时区信息吗? AFAIK ndb 期望日期时间为 UTC,这只会将带时区的本地日期时间转换为不带时区的本地日期时间,不是吗? (因此不是将 2000-01-01T04:00:00.000000-04:00 转换为 2000-01-01T00:00:00.000000,而是将其转换为 2000-01-01T04:00:00.000000)
    • @Hans 它确实删除了时区,但这正是 NDB 所期望的。 NDB 层存储时区原始日期时间,并依赖应用程序来整理从一个时区到下一个时区的转换。
    【解决方案2】:

    这是我的工作示例:

    if my_date.utcoffset():
        my_date = (my_date - my_date.utcoffset()).replace(tzinfo=None)
    

    【讨论】:

    • 也许将 if 语句改为: if my_date.utcoffset() is not None :
    【解决方案3】:

    我使用http://hnrss.org/ 遇到了这个问题。这是我的解决方案。

        import datetime
        from dateutil import parser
    
        your_date_string = 'Mon, 24 Oct 2016 16:49:47 +0000'
    
        your_date = parser.parse(your_date_string)
        # your_date is now a datetime.datetime object
    
        your_date_minus_tz = your_date.replace(tzinfo=None)
    

    现在尝试您的 put(),您应该会在 Cloud 数据存储中看到 2016-10-24 16:49:47。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-06
      • 1970-01-01
      • 2021-12-31
      • 2011-01-06
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多