1 引言在實(shí)際開發(fā)過程中,我們經(jīng)常會(huì)用到日期或者時(shí)間,那么在Python中我們?cè)趺传@取時(shí)間,以及如何將時(shí)間轉(zhuǎn)換為我們需要的格式呢?在之前的開發(fā)中,也曾遇到time、datetime等模塊下的不同函數(shù),這些函數(shù)名又很是相似,幾次下來(lái)頭都昏了,今天來(lái)徹底總結(jié)梳理一下Python中日期時(shí)間獲取與格式化。 2 理論準(zhǔn)備首先必須做一點(diǎn)理論準(zhǔn)備,不然待會(huì)都不知道為什么會(huì)有這些函數(shù)。介紹3個(gè)概念: UTC time Coordinated Universal Time,世界協(xié)調(diào)時(shí),又稱格林尼治天文時(shí)間、世界標(biāo)準(zhǔn)時(shí)間。與UTC time對(duì)應(yīng)的是各個(gè)時(shí)區(qū)的local time,也就是本地時(shí)間,例如我們的北京時(shí)間。 epoch time表示時(shí)間開始的起點(diǎn);它是一個(gè)特定的時(shí)間,不同平臺(tái)上這個(gè)時(shí)間點(diǎn)的值不太相同,對(duì)于Unix而言,epoch time為 1970-01-01 00:00:00 UTC。 timestamp(時(shí)間戳) 也稱為Unix時(shí)間 或 POSIX時(shí)間;它是一種時(shí)間表示方式,表示從格林尼治時(shí)間1970年1月1日0時(shí)0分0秒開始到現(xiàn)在所經(jīng)過的毫秒數(shù),其值為float類型。 但是有些編程語(yǔ)言的相關(guān)方法返回的是秒數(shù),例如我們的天下第一編程語(yǔ)言-Python大法就是這樣(請(qǐng)不要反駁我)。所謂的時(shí)間戳timestamp就是當(dāng)前時(shí)間與格林尼治時(shí)間1970年1月1日0時(shí)0分0秒之間過了多少秒。 相應(yīng)的,日期時(shí)間就有三種表示方法: 1)stamptime時(shí)間戳,時(shí)間戳表示的是從1970年1月1日00:00:00開始按秒計(jì)算的偏移量。stamptime表現(xiàn)為一個(gè)float類型數(shù)據(jù)。 2)struct_time時(shí)間元組,共有九個(gè)元素組。stamptime時(shí)間戳和格式化時(shí)間字符串之間的轉(zhuǎn)化必須通過struct_time才行,所以struct_time時(shí)間元組時(shí)3中時(shí)間表示的中心。 3)format time 格式化時(shí)間,已格式化的結(jié)構(gòu)字符串使時(shí)間更具可讀性。包括自定義格式和固定格式。 那么,下面要說(shuō)的就是怎么獲取這三個(gè)時(shí)間,并進(jìn)行這三個(gè)時(shí)間之間的轉(zhuǎn)化。先總結(jié)一下time模塊。 3 time模塊先放兩個(gè)圖:
time模塊中,幾乎所有時(shí)間獲取與格式轉(zhuǎn)化的函數(shù)都在上圖中了,只要理清了這幅圖的關(guān)系,那么time模塊就不再是問題。圖中,藍(lán)色方塊表示那三種時(shí)間格式,箭頭表示時(shí)間的轉(zhuǎn)化。下面,重點(diǎn)來(lái)了: 1)獲取當(dāng)前時(shí)間的方法只有一個(gè),那就是通過上圖中的函數(shù)1——time.time()。也就是說(shuō),要想獲取當(dāng)前時(shí)間,只能通過這個(gè)方法,而且獲取的是時(shí)間戳格式的時(shí)間。想直接獲取當(dāng)前時(shí)間的時(shí)間元組格式或格式化字符串?沒門,只能老老實(shí)實(shí)轉(zhuǎn)化。 2)當(dāng)傳入默認(rèn)參數(shù)時(shí),指的是使用當(dāng)前時(shí)間作為參數(shù)值。圖中帶黃色底紋的都是設(shè)有默認(rèn)值的參數(shù)(雖然默認(rèn)值為None),函數(shù)2、3不傳入該參數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)獲取當(dāng)前時(shí)間的時(shí)間戳作為該參數(shù)值。而函數(shù)5則是系統(tǒng)會(huì)自動(dòng)獲取當(dāng)前時(shí)間的時(shí)間元組作為該參數(shù)值,不是不能直接獲取當(dāng)前時(shí)間的時(shí)間元組嗎?是的,但系統(tǒng)會(huì)先獲取當(dāng)前時(shí)間的時(shí)間戳,然后轉(zhuǎn)化為時(shí)間元組。上圖中只有向左的箭頭所代表的函數(shù)才有默認(rèn)值,就是因?yàn)橄蛴也拍苡蓵r(shí)間戳轉(zhuǎn)化得到需要的時(shí)間格式。 3) localtime(函數(shù)2)和gmtime(函數(shù)3)都可以實(shí)現(xiàn)將時(shí)間戳轉(zhuǎn)化為時(shí)間元組,但是,localtime轉(zhuǎn)化的是本地時(shí)間,gmtime轉(zhuǎn)為的是世界標(biāo)準(zhǔn)時(shí)間。 4)asctime(函數(shù)7)和ctime(函數(shù)8)只能轉(zhuǎn)為為%a %b %d %H:%M:%S %Y格式的字符串時(shí)間。不傳入?yún)?shù)時(shí),用的也是當(dāng)前時(shí)間。 5)struct_time元組元素結(jié)構(gòu):
struct_time屬性值的獲取方式有兩種:
6)format time結(jié)構(gòu)化表示:
在代碼中實(shí)踐一下上面的內(nèi)容: 1)time.time() >>> import time
>>> time.time()
1544278402.1804464
2)time.localtime() >>> time.localtime() # 不傳入?yún)?shù) time.struct_time(tm_year=2018, tm_mon=12, tm_mday=8, tm_hour=22, tm_min=14, tm_sec=58, tm_wday=5, tm_yday=342, tm_isdst=0) >>> time.localtime(time.time()) # 傳入當(dāng)前時(shí)間 time.struct_time(tm_year=2018, tm_mon=12, tm_mday=8, tm_hour=22, tm_min=15, tm_sec=33, tm_wday=5, tm_yday=342, tm_isdst=0) >>> time.localtime(1544200000.1232) # 傳入其他時(shí)間戳 time.struct_time(tm_year=2018, tm_mon=12, tm_mday=8, tm_hour=0, tm_min=26, tm_sec=40, tm_wday=5, tm_yday=342, tm_isdst=0) 3)time.gctime() >>> time.gmtime() time.struct_time(tm_year=2018, tm_mon=12, tm_mday=8, tm_hour=14, tm_min=18, tm_sec=38, tm_wday=5, tm_yday=342, tm_isdst=0) 4)time.mktime() >>> time.mktime(time.localtime()) 1544279024.0 5)strftime(format, p_tuple=None) >>> time.strftime('%y-%m-%d' , time.localtime()) '18-12-08' >>> time.strftime('%Y-%m-%d' , time.localtime()) >>> time.strftime('%Y年%m月%d日 %M時(shí)%I分%S秒' , time.localtime()) '2018年12月08日 34時(shí)10分04秒' 6)strptime(string, format) >>> time.strptime('2018年12月08日 34時(shí)10分04秒' , '%Y年%m月%d日 %M時(shí)%I分%S秒') time.struct_time(tm_year=2018, tm_mon=12, tm_mday=8, tm_hour=10, tm_min=34, tm_sec=4, tm_wday=5, tm_yday=342, tm_isdst=-1) 7)asctime(p_tuple=None) >>> time.asctime() # 不傳入?yún)?shù),默認(rèn)是當(dāng)前時(shí)間 'Sat Dec 8 22:42:46 2018' >>> time.asctime(time.localtime(1544278402.1804464)) 'Sat Dec 8 22:13:22 2018' 8)ctime(seconds=None) >>> time.ctime() # 不傳入?yún)?shù) 'Sat Dec 8 22:45:58 2018' >>> time.ctime(1544278402.1804464) 'Sat Dec 8 22:13:22 2018' 4 datetime模塊datetime模塊是time模塊的進(jìn)一步封裝,對(duì)用戶更加友好,在時(shí)間各屬性的獲取上回更加方便一些,當(dāng)然,在效率上會(huì)略微低一些。datetime模塊的功能主要都幾種在datetime、date、time、timedelta、tzinfo五個(gè)類中。這五個(gè)類功能如下表所示:
4.1 date類先來(lái)說(shuō)說(shuō)date類,其定義如下: class datetime.date(year, month, day)
year, month 和 day都是是必須參數(shù),各參數(shù)的取值范圍為:
類方法和屬性
對(duì)象方法和屬性
4.2 time類定義格式: class datetime.time(hour, [minute[, second, [microsecond[, tzinfo]]]])
hour為必須參數(shù),其他為可選參數(shù)。各參數(shù)的取值范圍為:
類方法和屬性
對(duì)象方法和屬性
4.3 datetime類datetime類的定義如下: class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
year, month 和 day是必須要傳遞的參數(shù), tzinfo可以是None或tzinfo子類的實(shí)例。 各參數(shù)的取值范圍為:
如果一個(gè)參數(shù)超出了這些范圍,會(huì)引起ValueError異常。 類方法和屬性:
對(duì)象方法和屬性:
上面是date、time、datetime三個(gè)類的方法和屬性,關(guān)于這三個(gè)類,使用方法上基本與time模塊差不多,看方法名基本就一目了然,實(shí)在忘記,直接查表就好,本文不在過多介紹。 4.4 timedelta類timedelta可以方便實(shí)現(xiàn)日期(date實(shí)例、time實(shí)例、datetime實(shí)例)之間的加減運(yùn)算。 datetime.timedelta類的定義 class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, hours=0, weeks=0)
所有參數(shù)都是默認(rèn)參數(shù),因此都是可選參數(shù)。參數(shù)的值可以是整數(shù)或浮點(diǎn)數(shù),也可以是正數(shù)或負(fù)數(shù)。內(nèi)部值存儲(chǔ)days、seconds 和 microseconds,其他所有參數(shù)都將被轉(zhuǎn)換成這3個(gè)單位:
然后對(duì)這3個(gè)值進(jìn)行標(biāo)準(zhǔn)化,使得它們的表示是唯一的:
類屬性:
實(shí)例方法和屬性:
5 總結(jié)對(duì)于Python中時(shí)間、日期模塊的應(yīng)用主要集中在time模塊和datetime模塊中,其中涉及到的方法和屬性有些多容易混淆,可以以time模塊為出發(fā)點(diǎn),只要理清time模塊中3種時(shí)間格式之間的關(guān)系,就容易記憶了。 參考資料: https://blog.csdn.net/p9bl5bxp/article/details/54945920 |
|