Python2中生成時間戳(Epoch,或Timestamp)的常見誤區


在Python2中datetime對象沒有timestamp方法,不能很方便的生成epoch,現有方法沒有處理很容易導致錯誤。關於Epoch可以參見時區與Epoch

0 Python中生成Epoch

from datetime import datetime
# python3
datetime.now().timestamp()
# python2
import time
time.mktime(datetime.now().timetuple()) # 為了兼容python2和3,該用法使用更廣泛

1 錯誤代碼

from datetime import datetime
import pytz
aware_date = datetime.utcnow().replace(tzinfo=pytz.utc)
time.mktime(aware_date.timetuple()) # bug here

2 原因

Python中的datetime對象分為帶時區信息和不帶時區信息的兩種對象即naiveaware對象。在處理naive時,一切皆默認為系統時區,沒有任何問題。

在Python3中執行timestamp時對於naive對象,按照默認時區處理(調用time.mktime),而aware對象,則帶上時區計算與UTC基准時間的間隔秒數得到,也就是將時區信息考慮在內。

而Python2和3中的timetuple方法,返回的結果沒有包含時區信息,也沒有進行時區轉換。即調用timetuple對於aware日期對象而言,時區信息被丟棄,因此再調用time.mktime將得到一個錯誤的結果

3 解決辦法

  1. 方法一:將其他時區的aware日期,轉換為當前系統默認的時區的aware對象, 由於與系統時區一致,因此該aware對象與無時區的naive對象執行timetuple的效果一樣。
    轉換時區參見timezone,即調用astimezone方法,參數為轉換后的時區(tzinfo實例)
    由於Python2中缺失tzinfo(抽象基類)的各個時區實例,需要自己構造時區對象。
    時區實例可以參考官方文檔的實現datetime或使用推薦的第三方庫pytz

  2. 方法二:計算時間差

   _EPOCH = datetime(1970, 1, 1, tzinfo=pytz.utc) # 第三方庫 pytz
   (aware_date - _EPOCH).total_seconds()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM