程式扎記: [ Python 常見問題 ] formatting python timedelta objects

標籤

2013年3月16日 星期六

[ Python 常見問題 ] formatting python timedelta objects

來源自 這裡 
問題: 
在 Python 中有一個用來處理時間的 library: datetime - basic date and time object. 透過他你可以很方便的表示與處理時間, 舉例來說當你需要計算時間差時 (某個 task 花的時間), 你可以在開始某個工作開始執行前先執行 datetime.now() 獲得代表當前時間的 datetime 物件, 接著在執行完工作後再次執行 datetime.now() 並減掉之前獲得的 datetime 物件 (會得到 timedelta 物件.), 便可以得到執行前到執行後間的時間差: 
>>> import time
>>> from datetime import datetime
>>> before = datetime.now() # 紀錄執行工作前時間
... (執行工作)
>>> tdelta = datetime.now() - before # 計算執行前後的時間差
>>> tdelta
datetime.timedelta(0, 41, 732000) # 執行時間為 41.732 秒

現在問題來了, "(0, 41, 732000)" 的表示方法不容易懂, 因此你可以希望將之表示為 "xx 分 xx 秒" , 下面介紹幾個方法來處理 timedelta 物件的 format. 

方法一: 
我們可以參考 "strftime() and strptime() Behavior", 取出 timedelta 物件的資料然後丟入一個 HashMap, 在使用 string 的 printf 方式印出客製後格式的字串. 首先我們來撰寫代碼如下, 設計一個函數 strfdelta(tdelta, fmt) 並將 timedelta 物件 tdelta 根據格式字串 fmt 輸出我們的結果. 
  1. from string import Template  
  2.   
  3. class DeltaTemplate(Template):  
  4.     delimiter = "%"  
  5.   
  6. def strfdelta(tdelta, fmt):  
  7.     d = {"D": tdelta.days}  
  8.     d["H"], rem = divmod(tdelta.seconds, 3600)  
  9.     d["M"], d["S"] = divmod(rem, 60)  
  10.     t = DeltaTemplate(fmt)  
  11.     return t.substitute(**d)  
接著可以如下使用剛剛我們設計的函數 strfdelta()
>>> print strfdelta(delta_obj, "%D days %H:%M:%S")
1 days 20:18:12
>>> print strfdelta(delta_obj, "%H hours and %M to go")
20 hours and 18 to go

方法二: 
如果你的時間格式不常變的話, 其實可以不用如方法一這樣麻煩, 參考代碼如下: 
  1. import datetime as dt  
  2.   
  3. turnaround = dt.timedelta(days = 1, hours = 3, minutes = 42, seconds = 54)  
  4.   
  5. total_seconds = int(turnaround.total_seconds())  
  6. hours, remainder = divmod(total_seconds,60*60)  
  7. minutes, seconds = divmod(remainder,60)  
  8.   
  9. print('{} hrs {} mins {} secs'.format(hours,minutes,seconds))  
上面透過 timedelta 物件中的方法 total_seconds() 取出總秒數, 接著一一處理傳換成 hr, min 與 sec 並使用 print format 輸出.

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!