1

私のcronジョブの目的は、タイムスタンプ付きのツイートをGoogleAppEngineのデータストアに保存することです。データをタイムスタンプ形式で保存する方法を理解できませんでした(現在、文字列として保存されています)。理想的には、これをDateTimePropertyとして保存して、後でエントリを並べ替える時間を簡単にしたいと思います。私が苦労している特定の2つの問題があります:

  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()
4

1 に答える 1

1

次の形式を使用して、次の形式で時間文字列をスキャンする必要がありますdatetime.strptime

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

これはPython3で正しく機能します。

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ため、それ以上の操作は不要であることに注意してください。

残念ながら、これはPython2では機能しません。

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'

これはPython2.7のバグのようです。ドキュメントにはが記載されています%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文字が切り捨てられます。これは、タイムゾーンオフセットに符号と4桁がある場合にのみ正しく機能します。別の代替手段は、とを使用することsplitですjoin

>>> 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オブジェクトに配置する必要があります。

于 2013-03-24T09:39:38.853 に答える