在 app engine 使用 pytz

今天才意識到 timezone 的處理是有那麼一點麻煩, 存放、顯示要怎麼做之類的, 之前都沒處理過這類的問題, 不過也只能先解決問題, 之後有空在來深入研究 timezone。

這兩三天在用 appenginetwitter/plurk 備份的東西, 而 twitter 跟 plurk api 吐的訊息時間分別是 UTC +0000 跟 GMT, 不過剛剛網路上查了一下, 基本上、簡單來說 UTC = GMT, hmm 細節之後再來研究。所以說 twitter 或 plurk 的推訊時間都是用 UTF +0000, 不過這兩個的處理方式比較起來, twitter 簡單多了。

twitter api 的每則推訊都會有 user 的資料, 而 user 的資料當中 utc_offset 直接帶秒數, 例如我在台灣就是 28800 秒, 也就是 8 個小時, 所以就可以用以下的程式碼來把推訊的時間修正為準確, 符合 user 當地的時間

from datetime import datetime, timedelta<p>fmt = '%a %b %d %H:%M:%S +0000 %Y'  
created_at = datetime.strptime(message['created_at'], fmt)  
utc_offset = int(message['user']['utc_offset'])  
local_time = created_at + timedelta(seconds=utc_offset)</p>```

twitter 時間處理滿簡單的, 直接用回傳資料的 utc_offset 然後用 timedelta 處理即可, 即使 utc_offset 是負值也沒問題。 相對之下 Plurk 那邊可以讀到是 timezone, 如: “Asia/Taipei" 這組字串, 顯然麻煩了些。

網路上找了一下, 似乎用 [pytz](http://pytz.sourceforge.net/) 就可以很方便處理。 以下為 透過 pytz 用來為 plurk 處理本地時間的方式。

from datetime import datetime
from pytz import timezone

fmt = '%a, %d %b %Y %H:%M:%S GMT'
createdat = datetime.strptime(message['posted'], fmt)
user
timezone = timezone("Asia/Taipei")
localtime = createdat + usertimezone.utcoffset(createdat)```

使用 pytz 真的滿方便就可以處理掉 timezone 的 time offset 問題, 不過問題來了, pytz 的 zoneinfo 就有 600 個檔案了, 然而 app engine 好像上限是 1000 個檔案, 整個吃掉一半以上。 不過似乎有 zipimport 的方式可以把檔案先壓縮在丟上去, 所以 google 幾個方式之後, 最後找到這個方式最簡單, 不過文件沒寫太清楚, 所以在這邊記錄一下。

ok, 結果討人厭的事情又來了, pytz 現在放在 launchpad 阿 … 誰裝 bazar 阿 XD 不過幸好在 pypi 可以直接抓檔案。

首先就是抓 tz_helper 跟 pytz 回來, 然後把 pytz 解開後, 找到 zoneinfo 然後把它 zip 起來, 接著就可以把 zoneinfo 目錄刪了, 最後把這三個檔案放在 app 的根目錄就好了, 像是

/app.yaml /index.yaml /main.py ... /tz_helper.py /pytz /zoneinfo.zip

之後使用的時候直接 import tz_helper 的 timezone 來用即可。

其實現在 SNS 的時間大多都直接採用 3 hours ago 之類的方式來顯示時間, 我想最主要的原因就是, 這樣可以很容易因應世界各地使用者不同時區的問題, 而不是直接顯示這個日期。 誰知道我今天兩個方式都要有, 分別像是下面兩張圖的方式呈現, 所以就得處理 time offset 的問題。 總不能我在 5 月 5 號早上七點的推訊仍舊被記到 5 月 4 號。 而存放成台灣時間, 結果用 UTC +0000 去做 minutes ago, 顯示出來都是 0 minutes ago。

tzangms

Read more posts by this author.

Subscribe to Oceanic / 海海人生

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!