Python時間模塊,超實用總結!
今天是Python時間模塊核心使用邏輯。本篇思維導圖如下:
Python內置一個時間模塊datetime,提供我們關于時間的表達。記錄時間無所不在,日志文件,程序運行起始時間和時長,銷量預測的特征等等,我們都能看到時間的身影。
這篇專題總結datetime模塊最主要用法,希望通過此文,大家使用那些時間處理的常用API時,能信手拈來,不用help函數(shù),不用搜索。
1. 核心邏輯
datetime模塊提供日期和時間各自分類的對象,日期處理相關的對象date,時間處理相關的time,日期和時間的完整結合對象datetime.
日期和時間的加減操作得到timedelta對象.
此時此刻 2020-8-28 21:45,這個時間是本地時間,很明顯紐約時間肯定不是此值,柏林時間也肯定不是這個值。Python為支持不同地區(qū)的時間表達,特意抽象出tzinfo對象,并有一個默認實現(xiàn)對象.
以上就是datetime模塊的幾個核心對象以及對應的現(xiàn)實意義。
2. date、time和datetime對象
下面介紹最基本3個對象的最基本用法。首先,從datetime模塊導入3個對象
- In [1]: from datetime import date,time,datetime
構造一個日期date實例,2020年9月1日:
- In [2]: date(2020,9,1)
- Out[2]: datetime.date(2020, 9, 1)
構造一個時間time實例,10點10分0秒:
- In [3]: time(10,10,0)
- Out[3]: datetime.time(10, 10)
構造一個日期+時間的完整datetime實例,2020年9月1日 10點10分0秒:
- In [4]: datetime(2020,9,1,10,10,10)
- Out[4]: datetime.datetime(2020, 9, 1, 10, 10, 10)
自己構造時間沒什么意義,更有意義的是打印當前時間,比如此時程序啟動打印下時間,如果程序可能運行十幾天,很明顯使用日期+時間的完整datetime實例。
此方法歸屬于datetime類上的方法,所以無須構造datetime實例,直接如下:
- datetime.today() # datetime類的today方法
- Out[5]: datetime.datetime(2020, 8, 28, 22, 0, 47, 439509)
打印結果顯示年月日時分秒毫秒 還可以使用類方法now:
- In [6]: datetime.now()
- Out[6]: datetime.datetime(2020, 8, 28, 22, 1, 28, 737166)
直接打印當前時間,返回日期+時間的字符串結果:
- In [7]: print(datetime.now())
- 2020-08-28 22:02:57.217572
如果我們不想顯示毫秒,這就涉及到日期+時間的打印格式化問題。使用datetime類方法strftime(string format time),用法如下:
- In [8]: datetime.strftime(datetime.now(),'%Y-%m-%d %H:%M:%S')
- Out[8]: '2020-08-28 22:06:20'
這就涉及到打印格式化字符,常用的幾個:
如果讀入一個時間列,此時type為str,為了對此作時間運算,需要將其轉化為datetime,使用strptime(string parse time),它是datetime的類方法:
- In [11]: datetime.strptime('2020-08-28 22:06:20','%Y-%m-%d %H:%M:%S')
- Out[11]: datetime.datetime(2020, 8, 28, 22, 6, 20)
字符型日期+時間要想正確轉化為datetime對象,字符串和格式必須要匹配,否則會拋錯:
- In [13]: datetime.strptime('2020-08-28 22:06:20',\
- '%Y/%m/%d %H:%M:%S')
- ValueError: time data '2020-08-28 22:06:20'
- does not match format '%Y/%m/%d %H:%M:%S'
3. 基本運算
有時需要求偏離某個時間的時間,timedelta對象能滿足此需求。
比如,求當前時間的前12小時的日期+時間。
首先,導入timedelta類:
- In [15]: from datetime import timedelta
直接使用當前時間減去timedelta表示的12小時長度,注意第一個參數(shù)的含義為days,所以除以 24:
- In [16]: datetime.now() - timedelta(12/24)
- Out[16]: datetime.datetime(2020, 8, 28, 10, 22, 44, 287246)
由上面這個用法,可以總結為:
datetime1 - timedelta1 = datetime2
所以 datetime1 - datetime2 = timedelta1,故兩個時間相減得到timedelta類型的實例。
除此之外,還有一個小方法,可能會用到,就是datetime類上的combine方法,它能組合date實例和time實例為datetime實例,如下所示:
- In [17]: datetime.combine(date(2020,9,1),time(10,10,0))
- Out[17]: datetime.datetime(2020, 9, 1, 10, 10)
4 關于tzinfo
為了更好統(tǒng)一全球時間,世界規(guī)定了一個UTC時間,即全球統(tǒng)一時間,比如假設與之相比北京時間比它早8小時,曼谷比它早7小時等。
比如打印當前時間時,
- ```python
- In [6]: print(datetime.now())
- 2020-08-28 22:33:35.393709
以上顯示的這個時間,其實并不完整,我當然明白它是我所在地的時間,但是其他國家的開發(fā)者看到這個時間時,或許以為是UTC標準下的時間。若是這樣解讀,顯然會和實際有一個時差問題。
有的讀者會說,我在打印格式化時添加時區(qū)信息可以嗎,我們實驗一下:
- In [19]: datetime.strftime(datetime.now(),\
- '%Y-%m-%d %H:%M:%S %Z')
- Out[19]: '2020-08-28 22:39:44 '
時區(qū)信息為空,所以沒能解決問題。之所以時區(qū)信息會為空,是因為datetime.now()時未給定tzinfo值。
所以,我們需要自己重新定義一個tzinfo,即實現(xiàn)一個tzinfo對象。
此類BJinfo繼承tzinfo,然后實現(xiàn)其中的3個方法:
- from datetime import tzinfo
- class BJinfo(tzinfo):
- """BJinfo"""
- def utcoffset(self, dt):
- return timedelta(hours=8)
- def tzname(self, dt):
- return "UTC 8"
- def dst(self, dt):
- return timedelta(hours=8)
此時再打印當前時間時,賦上tzinfo值:
- nowt = datetime.now(tz=BJinfo())
- In [32]: In [6]: print(nowt)
- 2020-08-28 22:52:20.328446+08:00
再格式化打印時區(qū)信息:
- ...: '%Y-%m-%d %H:%M:%S %Z')
- 36]: '2020-08-28 22:52:20 UTC 8'
透過時區(qū)信息BJinfo 定義的三個方法,便能確認時間2020-08-28 22:52:20是比UTC快8個小時的時區(qū)下,所對應的一個時間。
總結
以上就是本專題對datetime模塊核心對象的使用總結,大綱如下:
- 核心邏輯
- date、time和datetime對象
- 基本運算
- 關于tzinfo