Python時間日期格式化之time與datetime模組總結
1 引言
2 理論準備
3 time模組
4 timedate模組
4.1 date類
4.2 time類
4.3 datetime類
4.4 datedelta類
1 引言
在實際開發過程中,我們經常會用到日期或者時間,那麼在Python中我們怎麼獲取時間,以及如何將時間轉換為我們需要的格式呢?在之前的開發中,也曾遇到time、datetime等模組下的不同函式,這些函式名又很是相似,幾次下來頭都昏了,今天來徹底總結梳理一下Python中日期時間獲取與格式化。
2 理論準備
首先必須做一點理論準備,不然待會都不知道為什麼會有這些函式。介紹3個概念:
UTC time Coordinated Universal Time,世界協調時,又稱格林尼治天文時間、世界標準時間。與UTC time對應的是各個時區的local time,也就是本地時間,例如我們的北京時間。
epoch time表示時間開始的起點;它是一個特定的時間,不同平臺上這個時間點的值不太相同,對於Unix而言,epoch time為 1970-01-01 00:00:00 UTC。
timestamp(時間戳) 也稱為Unix時間 或 POSIX時間;它是一種時間表示方式,表示從格林尼治時間1970年1月1日0時0分0秒開始到現在所經過的毫秒數,其值為float型別。 但是有些程式語言的相關方法返回的是秒數,例如我們的天下第一程式語言-Python大法就是這樣(請不要反駁我)。所謂的時間戳timestamp就是當前時間與格林尼治時間1970年1月1日0時0分0秒之間過了多少秒。
相應的,日期時間就有三種表示方法:
1)stamptime時間戳,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。stamptime表現為一個float型別資料。
2)struct_time時間元組,共有九個元素組。stamptime時間戳和格式化時間字串之間的轉化必須通過struct_time才行,所以struct_time時間元組時3中時間表示的中心。
3)format time 格式化時間,已格式化的結構字串使時間更具可讀性。包括自定義格式和固定格式。
那麼,下面要說的就是怎麼獲取這三個時間,並進行這三個時間之間的轉化。先總結一下time模組。
3 time模組
先放兩個圖:
time模組中,幾乎所有時間獲取與格式轉化的函式都在上圖中了,只要理清了這幅圖的關係,那麼time模組就不再是問題。圖中,藍色方塊表示那三種時間格式,箭頭表示時間的轉化。下面,重點來了:
1)獲取當前時間的方法只有一個,那就是通過上圖中的函式1——time.time()。也就是說,要想獲取當前時間,只能通過這個方法,而且獲取的是時間戳格式的時間。想直接獲取當前時間的時間元組格式或格式化字串?沒門,只能老老實實轉化。
2)當傳入預設引數時,指的是使用當前時間作為引數值。圖中帶黃色底紋的都是設有預設值的引數(雖然預設值為None),函式2、3不傳入該引數時,系統會自動獲取當前時間的時間戳作為該引數值。而函式5則是系統會自動獲取當前時間的時間元組作為該引數值,不是不能直接獲取當前時間的時間元組嗎?是的,但系統會先獲取當前時間的時間戳,然後轉化為時間元組。上圖中只有向左的箭頭所代表的函式才有預設值,就是因為向右才能由時間戳轉化得到需要的時間格式。
3) localtime(函式2)和gmtime(函式3)都可以實現將時間戳轉化為時間元組,但是,localtime轉化的是本地時間,gmtime轉為的是世界標準時間。
4)asctime(函式7)和ctime(函式8)只能轉為為%a %b %d %H:%M:%S %Y格式的字串時間。不傳入引數時,用的也是當前時間。
5)struct_time元組元素結構:
下標/索引 |
屬性名稱 |
描述 |
0 |
tm_year |
年份,如 2018 |
1 |
tm_mon |
月份,取值範圍為[1, 12] |
2 |
tm_mday |
一個月中的第幾天,取值範圍為[1-31] |
3 |
tm_hour |
小時, 取值範圍為[0-23] |
4 |
tm_min |
分鐘,取值範圍為[0, 59] |
5 |
tm_sec |
秒,取值範圍為[0, 61] |
6 |
tm_wday |
一個星期中的第幾天,取值範圍為[0-6],0表示星期一 |
7 |
tm_yday |
一年中的第幾天,取值範圍為[1, 366] |
8 |
tm_isdst |
是否為夏令時,可取值為:0 , 1 或 -1,預設值為-1 |
struct_time屬性值的獲取方式有兩種:
-
- 可以把它當做一種特殊的有序不可變序列通過 下標 / 索引 獲取各個元素的值,如t[0]
- 也可以通過物件名 “t . 屬性名 ” 的方式來獲取各個元素的值,如t.tm_year。
6)format time結構化表示:
格式 |
含義 |
%a |
本地(locale)簡化星期名稱 |
%A |
本地完整星期名稱 |
%b |
本地簡化月份名稱 |
%B |
本地完整月份名稱 |
%c |
本地相應的日期和時間表示 |
%d |
一個月中的第幾天(01 - 31) |
%H |
一天中的第幾個小時(24小時制,00 - 23) |
%I |
第幾個小時(12小時制,01 - 12) |
%j |
一年中的第幾天(001 - 366) |
%m |
月份(01 - 12) |
%M |
分鐘數(00 - 59) |
%p |
本地am或者pm的相應符 |
%S |
秒(01 - 61) |
%U |
一年中的星期數。(00 - 53星期天是一個星期的開始。)第一個星期天之前的所有天數都放在第0周。 |
%w |
一個星期中的第幾天(0 - 6,0是星期天) |
%W |
和%U基本相同,不同的是%W以星期一為一個星期的開始。 |
%x |
本地相應日期 |
%X |
本地相應時間 |
%y |
去掉世紀的年份(00 - 99) |
%Y |
完整的年份 |
%Z |
時區的名字(如果不存在為空字元) |
%% |
‘%’字元 |
在程式碼中實踐一下上面的內容:
1)time.time()
>>> import time >>> time.time() 1544278402.1804464
2)time.localtime()
>>> time.localtime() # 不傳入引數 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()) # 傳入當前時間 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) # 傳入其他時間戳 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()) '2018-12-08' >>> time.strftime('%Y年%m月%d日 %M時%I分%S秒' , time.localtime()) '2018年12月08日 34時10分04秒'
6)strptime(string, format)
>>> time.strptime('2018年12月08日 34時10分04秒' , '%Y年%m月%d日 %M時%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() # 不傳入引數,預設是當前時間 'Sat Dec8 22:42:46 2018' >>> time.asctime(time.localtime(1544278402.1804464)) 'Sat Dec8 22:13:22 2018'
8)ctime(seconds=None)
>>> time.ctime() # 不傳入引數 'Sat Dec8 22:45:58 2018' >>> time.ctime(1544278402.1804464) 'Sat Dec8 22:13:22 2018'
4 datetime模組
datetime模組是time模組的進一步封裝,對使用者更加友好,在時間各屬性的獲取上回更加方便一些,當然,在效率上會略微低一些。datetime模組的功能主要都幾種在datetime、date、time、timedelta、tzinfo五個類中。這五個類功能如下表所示:
類名 |
功能 |
date |
提供日期(年、月、日)的處理 |
time |
提供時間(時、分、秒)的處理 |
datetime |
同時提供對日期和時間的處理 |
timedelta |
兩個date、time、datetime例項之間的時間間隔(時間加減運算) |
tzinfo |
時區資訊 |
4.1 date類
先來說說date類,其定義如下:
class datetime.date(year, month, day)
year, month 和 day都是是必須引數,各引數的取值範圍為:
引數名稱 |
取值範圍 |
year |
[MINYEAR, MAXYEAR] |
month |
[1, 12] |
day |
[1, 指定年份的月份中的天數] |
類方法和屬性
類方法/屬性名稱 |
描述 |
date.max |
date物件所能表示的最大日期:9999-12-31 |
date.min |
date物件所能表示的最小日誌:00001-01-01 |
date.resoluation |
date物件表示的日期的最小單位:天 |
date.today() |
返回一個表示當前本地日期的date物件 |
date.fromtimestamp(timestamp) |
根據跟定的時間戳,返回一個date物件 |
物件方法和屬性
物件方法/屬性名稱 |
描述 |
d.year |
年 |
d.month |
月 |
d.day |
日 |
d.replace(year[, month[, day]]) |
生成並返回一個新的日期物件,原日期物件不變 |
d.timetuple() |
返回日期對應的time.struct_time物件 |
d.toordinal() |
返回日期是是自 0001-01-01 開始的第多少天 |
d.weekday() |
返回日期是星期幾,[0, 6],0表示星期一 |
d.isoweekday() |
返回日期是星期幾,[1, 7], 1表示星期一 |
d.isocalendar() |
返回一個元組,格式為:(year, weekday, isoweekday) |
d.isoformat() |
返回‘YYYY-MM-DD’格式的日期字串 |
d.strftime(format) |
返回指定格式的日期字串,與time模組的strftime(format, struct_time)功能相同 |
4.2 time類
定義格式:
class datetime.time(hour, [minute[, second, [microsecond[, tzinfo]]]])
hour為必須引數,其他為可選引數。各引數的取值範圍為:
引數名稱 |
取值範圍 |
hour |
[0, 23] |
minute |
[0, 59] |
second |
[0, 59] |
microsecond |
[0, 1000000] |
tzinfo |
tzinfo的子類物件,如timezone類的例項 |
類方法和屬性
類方法/屬性名稱 |
描述 |
time.max |
time類所能表示的最大時間:time(23, 59, 59, 999999) |
time.min |
time類所能表示的最小時間:time(0, 0, 0, 0) |
time.resolution |
時間的最小單位,即兩個不同時間的最小差值:1微秒 |
物件方法和屬性
物件方法/屬性名稱 |
描述 |
t.hour |
時 |
t.minute |
分 |
t.second |
秒 |
t.microsecond |
微秒 |
t.tzinfo |
返回傳遞給time構造方法的tzinfo物件,如果該引數未給出,則返回None |
t.replace(hour[, minute[, second[, microsecond[, tzinfo]]]]) |
生成並返回一個新的時間物件,原時間物件不變 |
t.isoformat() |
返回一個‘HH:MM:SS.%f’格式的時間字串 |
t.strftime() |
返回指定格式的時間字串,與time模組的strftime(format, struct_time)功能相同 |
4.3 datetime類
datetime類的定義如下:
class datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
year, month 和 day是必須要傳遞的引數, tzinfo可以是None或tzinfo子類的例項。
各引數的取值範圍為:
引數名稱 |
取值範圍 |
year |
[MINYEAR, MAXYEAR] |
month |
[1, 12] |
day |
[1, 指定年份的月份中的天數] |
hour |
[0, 23] |
minute |
[0, 59] |
second |
[0, 59] |
microsecond |
[0, 1000000] |
tzinfo |
tzinfo的子類物件,如timezone類的例項 |
如果一個引數超出了這些範圍,會引起ValueError異常。
類方法和屬性:
類方法/ 屬性名稱 |
描述 |
datetime.today() |
返回一個表示當前本期日期時間的datetime物件 |
datetime.now([tz]) |
返回指定時區日期時間的datetime物件,如果不指定tz引數則結果同上 |
datetime.utcnow() |
返回當前utc日期時間的datetime物件 |
datetime.fromtimestamp(timestamp[, tz]) |
根據指定的時間戳建立一個datetime物件 |
datetime.utcfromtimestamp(timestamp) |
根據指定的時間戳建立一個datetime物件 |
datetime.combine(date, time) |
把指定的date和time物件整合成一個datetime物件 |
datetime.strptime(date_str, format) |
將時間字串轉換為datetime物件 |
物件方法和屬性:
物件方法/ 屬性名稱 |
描述 |
dt.year, dt.month, dt.day |
年、月、日 |
dt.hour, dt.minute, dt.second |
時、分、秒 |
dt.microsecond, dt.tzinfo |
微秒、時區資訊 |
dt.date() |
獲取datetime物件對應的date物件 |
dt.time() |
獲取datetime物件對應的time物件, tzinfo 為None |
dt.timetz() |
獲取datetime物件對應的time物件,tzinfo與datetime物件的tzinfo相同 |
dt.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]]) |
生成並返回一個新的datetime物件,如果所有引數都沒有指定,則返回一個與原datetime物件相同的物件 |
dt.timetuple() |
返回datetime物件對應的tuple(不包括tzinfo) |
dt.utctimetuple() |
返回datetime物件對應的utc時間的tuple(不包括tzinfo) |
dt.toordinal() |
同date物件 |
dt.weekday() |
同date物件 |
dt.isocalendar() |
同date獨享 |
dt.isoformat([sep]) |
返回一個‘%Y-%m-%d |
dt.ctime() |
等價於time模組的time.ctime(time.mktime(d.timetuple())) |
dt.strftime(format) |
返回指定格式的時間字串 |
上面是date、time、datetime三個類的方法和屬性,關於這三個類,使用方法上基本與time模組差不多,看方法名基本就一目瞭然,實在忘記,直接查表就好,本文不在過多介紹。
4.4 timedelta類
timedelta可以方便實現日期(date例項、time例項、datetime例項)之間的加減運算。
datetime.timedelta類的定義
class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, hours=0, weeks=0)
所有引數都是預設引數,因此都是可選引數。引數的值可以是整數或浮點數,也可以是正數或負數。內部值儲存days、seconds 和 microseconds,其他所有引數都將被轉換成這3個單位:
- 1毫秒轉換為1000微秒
- 1分鐘轉換為60秒
- 1小時轉換為3600秒
- 1週轉換為7天
然後對這3個值進行標準化,使得它們的表示是唯一的:
- microseconds : [0, 999999]
- seconds : [0, 86399]
- days : [-999999999, 999999999]
類屬性:
類屬性名稱 |
描述 |
timedelta.min |
timedelta(-999999999) |
timedelta.max |
timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999) |
timedelta.resolution |
timedelta(microseconds=1) |
例項方法和屬性:
例項方法/屬性名稱 |
描述 |
td.days |
天 [-999999999, 999999999] |
td.seconds |
秒 [0, 86399] |
td.microseconds |
微秒 [0, 999999] |
td.total_seconds() |
時間差中包含的總秒數,等價於: td / timedelta(seconds=1) |
5 總結
對於Python中時間、日期模組的應用主要集中在time模組和datetime模組中,其中涉及到的方法和屬性有些多容易混淆,可以以time模組為出發點,只要理清time模組中3種時間格式之間的關係,就容易記憶了。
參考資料:
https://blog.csdn.net/p9bl5bxp/article/details/54945920