如何将时间戳插入GQL DateTimeProperty()?

时间:2013-03-24 07:36:51

标签: python google-app-engine datetime python-2.7 gql

我的cron工作的目标是将带有时间戳的推文保存到Google App Engine的数据存储区中。我无法弄清楚如何以时间戳形式保存数据(它当前保存为字符串)。理想情况下,我想将其保存为DateTimeProperty,以便更轻松地对条目进行排序。我正在努力解决两个特别的问题:

  1. 正确使用time.mktime()和
  2. 将正确的格式化值放入GQL
  3. 这个字段在json中形成如下:

    s = "Wed, 20 Mar 2013 05:39:25 +0000"
    

    我尝试使用datetime模块来解析此字符串:

    timestr = datetime.datetime.strptime(s, "%a, %b %Y %d %H:%M:%S +0000")
    when = datetime.fromtimestamp(time.mktime(timestr))
    

    总结一下,这是我的cron.py文件的片段:

    result = simplejson.load(urllib.urlopen(twitterurl))
    for item in result['results']:
    
    g = ""
    try:
        g = simplejson.dumps(item['geo']['coordinates'])
    except:
        pass
    
    timestr = datetime.datetime.strptime(str(item['created_at']), "%a, %b %Y %d %H:%M:%S +0000")
    when = datetime.fromtimestamp(time.mktime(timestr))
    
    tStore = TweetsFromJSON(user_id=str(item['from_user_id']),
                            user=item['from_user'], 
                            tweet=unicodedata.normalize('NFKD', item['text']).encode('ascii', 'ignore'),
                            timestamp=when,
                            iso=item['iso_language_code'], 
                            geo=g
                            )
    

    数据存储区的模型是:

    class TweetsFromJSON(db.Model):
        user = db.TextProperty()
        user_id = db.TextProperty()
        tweet = db.TextProperty()
        timestamp = db.DateTimeProperty()
        iso = db.StringProperty()
        geo = db.StringProperty()
    

1 个答案:

答案 0 :(得分:1)

您应使用以下格式使用datetime.strptime扫描时间字符串:

"%a, %d %b %Y %H:%M:%S %z"

这在Python 3中正常工作:

Python 3.3.0 (default, Mar 22 2013, 20:14:41) 
[GCC 4.2.1 Compatible FreeBSD Clang 3.1 ((branches/release_31 156863))] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> s = 'Wed, 20 Mar 2013 05:39:25 +0000'
>>> datetime.strptime(s, "%a, %d %b %Y %H:%M:%S %z")
datetime.datetime(2013, 3, 20, 5, 39, 25, tzinfo=datetime.timezone.utc)

请注意,这会返回一个datetime对象,因此不需要进一步操作。

不幸的是,这在Python 2中不起作用;

Python 2.7.3 (default, Jan 17 2013, 21:23:30) 
[GCC 4.2.1 Compatible FreeBSD Clang 3.0 (branches/release_30 142614)] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> s = 'Wed, 20 Mar 2013 05:39:25 +0000'
>>> datetime.strptime(s, "%a, %d %b %Y %H:%M:%S %z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%a, %d %b %Y %H:%M:%S %z'

这似乎是Python 2.7中的一个错误。 documentation提及%z,但/usr/local/lib/python2.7/_strptime.py中的代码不包含与其匹配的正确正则表达式。

作为Python 2的解决方法,您可以尝试:

>>> datetime.strptime(s[:-6], "%a, %d %b %Y %H:%M:%S")
datetime.datetime(2013, 3, 20, 5, 39, 25)

这只会切断最后6个字符。只有当时区偏移有一个符号和四位数时,这才能正常工作。另一个替代方案是使用splitjoin

>>> datetime.strptime(' '.join(s.split()[:-1]), "%a, %d %b %Y %H:%M:%S")
datetime.datetime(2013, 3, 20, 5, 39, 25)

根据我的理解,您必须自己扫描时区信息,创建自定义tzinfo子类(使用链接文档中的FixedOffset类示例)并使用datetime.replace()放置datetime对象中的那个。