2013-03-24 40 views
1

我的cron作业的目标是将带有时间戳的推文保存到Google App Engine的数据存储中。我一直无法弄清楚如何以时间戳形式保存数据(它目前保存为一个字符串)。理想情况下,我想将它保存为DateTimeProperty,以便更方便地对输入条目进行排序。还有特别是我挣扎了两个问题:如何将时间戳插入到GQL DateTimeProperty()?

  1. 正确使用time.mktime(),并
  2. 把正确格式化值到GQL

该油田在格式化像这样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

应使用以下格式用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个字符。如果时区偏移量有符号和四位数字,这只会正确工作。另一个alterantive是使用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的对象中。