Python 時間/時區處理筆記
很常用到的 function,可是三不五時都要去尻以前的 Code 來用有點麻煩
乾脆直接寫在這,以後來這邊尻!
取得 timestamp 與轉換
1 2 3 4 5 6 7 8 9 10 11 12
| import time import datetime ts = time.time() ts_str = datetime.strftime('%s') time.mktime(datetime.now().timetuple()) dt_obj = datetime.datetime.fromtimestamp(ts)
|
用字串轉成 datetime 物件
1
| dt_obj = datetime.datetime.strptime('2016-08-20 11:21:00','%Y-%m-%d %H:%M:%S')
|
datetime object 變換/加減
1 2 3 4 5 6
| from datetime import datetime, timedelta new_date = datetime.now().replace(days=1, hours=2, minutes=3) offset_dt = datetime.now() + timedelta(days=2, hours=5, minutes=30) offset_dt = datetime.now() - timedelta(days=0, hours=5, minutes=30)
|
用 pytz 做時區轉換
1 2 3 4 5 6 7 8 9 10 11
| import pytz from datetime import datetime datetime_obj = datetime.strptime('2016-08-20 11:21:00', '%Y-%m-%d %H:%M:%S') br_tz = pytz.timezone('America/Sao_Paulo') br_local_date = br_tz.localize(datetime_obj, is_dst=None)
|
要注意 python 的 datetime.timetuple 物件並沒有包含 timezone 資訊,
所以如果想把帶有 tzinfo 的 datetime 物件轉出 utc 會有一些問題。
看看以下例子。
1 2 3 4 5 6
| br_local_date.timetuple() br_local_date.utctimetuple()
|
所以我們來做個實驗
1 2 3 4 5 6 7
| test_date = datetime.strptime('2016-08-20 11:21:00', '%Y-%m-%d %H:%M:%S') time.mktime(test_date.timetuple()) time.mktime(br_local_date.timetuple())
|
疑?兩個一樣捏,我不是已經把 br_local_date 掛上 tzinfo 了嗎?
我不是應該拿到台灣當地時間 2016-08-20 11:21:00 的 utc
跟巴西聖保羅當地時間 2016-08-20 11:21:00 的 utc 嗎?
因為 time.mktime 會拿你本地系統時區去轉 timestamp,不是看 tzinfo。
而 calendar.timegm 不會自動幫你加時區。
所以做法就是要先把帶有 tzinfo 的 datetime 物件轉到 utc timezone,
再透過 calendar + datetime.utctimetuple() 把正確的 timestamp 轉出來!
這個雷踩過幾次,要特別小心。
想把巴西當地時間的 2016-08-20 11:21:00 轉成 utc 的完整範例:
1 2 3 4 5 6 7 8 9 10 11 12
| import calendar import pytz from datetime import datetime datetime_obj = datetime.strptime('2016-08-20 11:21:00', '%Y-%m-%d %H:%M:%S') br_tz = pytz.timezone('America/Sao_Paulo') br_local_date = br_tz.localize(datetime_obj, is_dst=None) br_utc = br_local_date.astimezone(pytz.timezone('utc')) calendar.timegm(br_utc.utctimetuple())
|
Refs
卡西哥的文章