詳解Python常用標準庫之時間模塊time和datetime
time時間模塊
import time
time -- 獲取本地時間戳
時間戳又被稱之為是Unix時間戳,原本是在Unix系統(tǒng)中的計時工具。
它的含義是從1970年1月1日(UTC/GMT的午夜)開始所經(jīng)過的秒數(shù),不考慮閏秒。UNIX時間戳的 0 按照ISO 8601規(guī)范為 :1970-01-01T00:00:00Z。
比如:
- 時間戳 60 表示 1970-01-01T00:01:00Z
- 時間戳 120 表示 1970-01-01T00:02:00Z
- 時間戳 3600 表示 1970-01-01T01:00:00Z
小知識:最開始的時候,時間戳的開始年份是1971年,那個時候Unix系統(tǒng)和C語言剛剛誕生,所以時間戳0也就是Unix系統(tǒng)和C語言的生日。那時候的時間位數(shù)只有32位,而且每秒中有60個數(shù)字,發(fā)現(xiàn)只要兩年多的時間時間戳就能完成一個輪回,十分的不方便!所以后來的一系列改革,將時間戳的數(shù)值改為每秒1個數(shù)字,還有一些新的系統(tǒng)可以將時間戳的位數(shù)增大,可以讓時間戳的輪回擴展到一百多年,再后來為了方便人們記憶,將時間戳的起始年份定位1970年整。
import time stamp_time = time.time() print(stamp_time) # 1635768368.2838552
localtime -- 獲取本地時間元組(UTC)
參數(shù)為時間戳,默認為本地時間戳,獲取時間元組。
時間元組是python中的一個特殊的數(shù)據(jù)類型type: time.struct_time
,但是它和tuple
的特性是相同的。
import time # 時間元組中的值分別表示: # tm_year: 年 # tm_mon: 月 # tm_mday: 日 # tm_hour: 時 # tm_min: 分 # tm_sec: 秒 # tm_wday: 周幾(0表示星期一) # tm_yday: 一年中的第幾天(從1開始) # tm_isdst: 夏令標識(1夏令時、0非夏令時、-1未知) # 默認當(dāng)前時間 time_tuple = time.localtime() print(time_tuple) # time.struct_time(tm_year=2021, tm_mon=11, tm_mday=1, tm_hour=20, tm_min=7, tm_sec=50, tm_wday=0, tm_yday=305, tm_isdst=0) # 指定時間戳 time_tuple = time.localtime(3600) print(time_tuple) # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=9, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
有大問題啦?。。?/p>
時間戳的起始時間是1970-1-1 0:0:0, 這個時候的時間戳是0,那么時間戳3600就是整整一個小時之后,那么時間就應(yīng)該是1970-1-1 0:1:0 才對的呀!怎么上面的3600確實9點鐘了呢?怎么起始時間變成了8點了呢?
然后你發(fā)現(xiàn)你在中國,時間是北京時間,北京在東八區(qū)時區(qū),嘶,怎么正好也是個八?
是這樣的,按照道理來說的話全世界任何一個地方的時間戳所代表的時間都應(yīng)該是一樣的,而且時間戳的起始時間確實是 1970-1-1 0:0:0 ,但是這個時間是位于英國的一個叫做格林威治的小鎮(zhèn)的,格林威治有一個天文臺叫做皇家格林尼治天文臺,后來國際上將這個地方的經(jīng)線作為本初子午線,作為時間計算時間和地理精度的起點。那么,有時區(qū)的存在打破了這個可能,我們在中國,所有的設(shè)備都是按照中國的時區(qū)編碼的,中國位于東八區(qū),在時間上比英國快八個小時,所以我們中國的本地時間戳就是 1970-1-1 8:00:00。
gmtime -- 獲取時間元組(GMT)
在不知道這個函數(shù)的時候,我就很好奇為什么localtime
的初始時間比格林威治時間要快8小時,現(xiàn)在就明白了:
函數(shù) | 描述 |
---|---|
gmtime | 獲取時間元組(GMT格林威治時間) |
localtime | 獲取時間元組(UTC協(xié)調(diào)世界時) |
mktime -- 時間元組獲取時間戳
注意:
- 參數(shù)必須是時間元組
time.struct_time
或者元組tuple
類型; - 元組中的元素一個也不能少,必須九個元素都存在;
- 得到的時間戳只收到前六個值的影響,即:年月日時分秒;
- 時間元組中的時間表示,最小時間不能低于當(dāng)?shù)氐淖钚r間戳;
- 時間元組中的時間表示,單位可以超出原本的范圍,比如秒滿60進1,我們將秒寫成100,系統(tǒng)也不會報錯,但是時間上會自動的將多出的時間進位。但是數(shù)字也不能過大,因為數(shù)據(jù)類型的大小是有極限的。
- mktime返回的數(shù)值是浮點型的,但是精度只能到1;
import time # 在中國的最小時間單位 tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0) time_stamp = time.mktime(tst) print(time_stamp) # 0.0
ctime -- 獲取時間字符串
參數(shù)默認為本地時間戳,獲取的數(shù)據(jù)類型是 str
,這個時間字符串不像時間元組是一個單獨的數(shù)據(jù)類型。
import time # 時間字符串中的含義是: # Mon Nov 1 21:34:39 2021 # 星期 月 日 時 分 秒 年 # 默認為本地時間戳 time_char = time.ctime() print(time_char) # Mon Nov 1 21:34:39 2021 # 指定時間戳 time_char = time.ctime(0) print(time_char) # Thu Jan 1 08:00:00 1970
asctime -- 時間元組獲取時間字符串
注意,asctime有弊端,看下例:
import time tst = (1970, 1, 1, 8, 24, 61, 1, 0, 0) time_char = time.asctime(tst) print(time_char) # Tue Jan 1 08:24:61 1970 tst = (1970, 1, 1, 8, 24, 61, 2, 0, 0) time_char = time.asctime(tst) print(time_char) # Tue Jan 1 08:24:61 1970
看上面的例子,時間元組變成時間字符串的時候,會將星期的數(shù)據(jù)也讀取到,但是卻不會分辨數(shù)據(jù)是否正確,所以asctime并不常用。
如果要將一個不確定正確性的時間元組變成時間字符串的話,先通過 mktime
獲取時間戳(mktime可以分辨出正確的時間信息),然后在將時間戳通過 ctime
變成時間字符串。
strftime -- 格式化時間
格式化時間,按照指定的格式(一段格式化字符串,就像字符串的格式化一樣)將時間元組變成時間字符串。
我們先來學(xué)習(xí)一下時間占位符的含義是什么:
注意?。?!這些占位符的大小寫的含義是不同的:
占位符 | 含義 |
---|---|
%Y | 以十進制數(shù)字表示以世紀為單位的年份(四位數(shù)) |
%y | 以十進制數(shù)字表示年份(兩位數(shù)) |
%m | 以十進制數(shù)字表示月份 |
%D | 以月/日/年(兩位數(shù))的格式表示年月日 |
%d | 以十進制數(shù)字表示日期 |
%H | 以十進制數(shù)字表示二十四小時制的時 |
%M | 以十進制數(shù)字表示分鐘 |
%S | 以十進制數(shù)字表示秒 |
%z | 與UTC的時區(qū)偏移 |
%a | 區(qū)域設(shè)置的縮寫工作日名稱 |
%A | 區(qū)域設(shè)置的完整工作日名稱 |
%b | 區(qū)域設(shè)置的縮寫月份名稱 |
%B | 區(qū)域設(shè)置的完整月份名稱 |
%c | 語言環(huán)境的適當(dāng)日期和時間表示 |
%I | 以十進制數(shù)表示十二小時制的時(大寫 ‘愛’) |
%p | 語言環(huán)境的等效值:AM 或者 PM |
現(xiàn)在根據(jù)使用時間占位符用字符串格式化將時間元組變成字符串。
import time # 注意,如果格式化字符串中出現(xiàn)中文字符,只能在linux系統(tǒng)下運行,windows下不能解析,直接報錯。 tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0) time_tuple = time.strftime('%Y-%m-%d-%H-%m-%S',tst) print(time_tuple) # 1970-01-01-08-01-00 # 有中文在windows下報錯 tst = (1970, 1, 1, 8, 0, 0, 0, 0, 0) time_tuple = time.strftime('%Y-%m哈哈-%d-%H-%m-%S',tst) print(time_tuple) # 1970-01-01-08-01-00
strptime -- 格式化時間
格式化時間,通過格式化字符串將一個字符串中的時間變成時間元組。
import time # 格式化字符串要和原字符串一模一樣,只是將需要提出的部分使用占位符替換 char = '2000年10月30日一個偉大的中國少年在三晉大地誕生了' format_char = '%Y年%m月%d日一個偉大的中國少年在三晉大地誕生了' tst = time.strptime(char, format_char) print(tst)
sleep -- 時間睡眠
等待指定秒數(shù)的時間:
import time print('開始睡覺') time.sleep(2) print('睡了兩秒鐘,神清氣爽')
perf_counter -- 時間計時
用于計算程序運行的時間
import time # perf_counter 用于計算程序運行的時間 # 記錄開始時間 start_time = time.perf_counter() # 程序運行 for i in range(10000): pass # 記錄時間 end_time = time.perf_counter() # windows系統(tǒng)直接拿到第二次的值就可以了,不用減去第一次的值也行 print(end_time, '秒') # 0.0003918 秒 print(end_time - start_time, '秒') # 0.0003916 秒
如果使用多次perf_counter()
函數(shù),直接輸出其的值是距第一次使用的時間長度:
import time time1 = time.perf_counter() time.sleep(1) time2 = time.perf_counter() print(time2) time.sleep(2) time3 = time.perf_counter() print(time3) time.sleep(3) time4 = time.perf_counter() print(time4) """ 結(jié)果: 1.0002558 3.0048941 6.019172 """
注意:windows系統(tǒng)下使用perf_counter()
函數(shù)可以直接輸出耗時長度,每次的耗時默認都是距離第一次使用perf_counter()
函數(shù)的時間長度;如果在linux系統(tǒng)下使用perf_counter()
函數(shù)則必須要使用第二次的結(jié)果減去之前的結(jié)果,因為在linux系統(tǒng)中perf_counter()
函數(shù)的值和time()
函數(shù)的值都是一樣的,那就是返回一個時間戳。
使用time.time()
計算時間
import time # perf_counter 用于計算程序運行的時間 # 記錄開始時間 start_time = time.time() # 程序運行 for i in range(10000): pass # 記錄時間 end_time = time.time() print(end_time - start_time, '秒') # 0.001001119613647461 秒
耗時短的計時推薦使用pref_counter
,耗時長的推薦使用time
。
模擬進度條
# 1、定義進度條樣式 print('[%-50s]' % ('###########')) print('[%-50s]' % ('###################')) print('[%-50s]' % ('###########################')) print('[%-50s]' % ('####################################')) print('[%-50s]' % ('########################################'))
# 2、讓進度條動起來 import time progress_char = '' for i in range(50): progress_char += '#' time.sleep(0.05) # 延時看起來不是很快 # end使不能換行,\r使進度條不斷刷新,保持在同一行顯示; print('\r[%-50s]' % (progress_char), end='') print('\n')
# 3、根據(jù)文件的大小調(diào)整進度條的進度 import time def progress(percent): """控制進度條的顯示 參數(shù)是下載的百分比,用來控制進度條的進展 """ # 如果百分比超過了1,說明數(shù)據(jù)已經(jīng)接受完畢 if percent > 1: percent = 1 # 打印對應(yīng)的進度條效果 char = '#' * int(percent * 50) print('\r[%-50s]%d%%' % (char, int(percent * 100)), end='') # 已下的大小 rec_size = 0 # 下載文件的大小 total_size = 102400 # 模擬下載過程 while rec_size < total_size: rec_size += 10240 # 下載速度 time.sleep(0.05) # 模擬網(wǎng)絡(luò)延遲 percent = rec_size / total_size # 計算下載的進度(百分比) # 調(diào)用進度條 progress(percent)
程序計時
在學(xué)習(xí)了perf_counter
計時后,我們知道有很多種方法可以用于計時:
1.time函數(shù):返回當(dāng)前時間戳,使用time函數(shù)計時是獲取兩個節(jié)點各自的時間戳,然后計算其之間的差值,即為耗時時長。
- 優(yōu)點:計算的是真實世界中的時間長度,而且計時本身不消耗計算機資源,計算長時間的程序優(yōu)勢較大;
- 缺點:time函數(shù)的時間獲取來源于計算機本身的時間,如果在計時途中計算機的時間發(fā)生變化,比如人為的調(diào)快一小時,那么計時就會比正確的時間慢一個小時的時間。
2.perf_counter函數(shù):是time模塊中專門用于性能計時的函數(shù),具有高分辨率的時鐘,已測量短持續(xù)的時間。
- 優(yōu)點:是專門用于性能計時的函數(shù),精確度高,適合計算耗時短的程序;
- 缺點:專門用于計時的函數(shù),計時本身就會消耗計算機資源,所以計時過長難免會有一定的影響;
3.process_time函數(shù):用于評測處理時間,計算內(nèi)核和用戶空間CPU時間之和,這個時間不包含程序阻塞的時間,比如time.sleep()、input()等。
優(yōu)點:專門用于計算程序本身內(nèi)在的時間消耗,排除外來因素、提升系統(tǒng)本身效率、優(yōu)化程序使用;
import time def loop(): time.sleep(1) input('請輸入:') # 這個位置人為數(shù)三秒回車執(zhí)行 num = 10 ** 8 for _ in range(num): pass time.sleep(1) # time.time start_time = time.time() loop() end_time = time.time() print(start_time) # 1640270620.4077902 print(end_time) # 1640270628.1165576 print(end_time - start_time) # 7.708767414093018 # time.perf_counter start_time = time.perf_counter() loop() end_time = time.perf_counter() print(start_time) # 3e-07 print(end_time) # 7.823952 print(end_time - start_time) # 7.8239517 # time.process_time start_time = time.process_time() loop() end_time = time.process_time() print(start_time) # 3.234375 print(end_time) # 4.8125 print(end_time - start_time) # 1.578125
除此之外,python3.7之后,新增了精確到納秒的函數(shù):
- time.time_ns()
- time.perf_counter_ns()
- time.process_time_ns()
還有標準庫timeit
用于程序的性能計時。
時間轉(zhuǎn)換示意圖
在上述的幾種類型中存在時間轉(zhuǎn)換的問題,詳情和之間的關(guān)系可以參考下圖:
datetime時間模塊
import datatime
datatime
模塊重新封裝了time模塊,提供更多的接口。
date類
date
類專門用于描述日期,實例化對象時必須填入?yún)?shù),分別表示:年、月、日,返回datetime.date
對象。
datetime.date(year, month, day)
from datetime import date date_o = date(2022, 3, 1) print(date_o) print(type(date_o)) """ 結(jié)果: 2022-03-01 <class 'datetime.date'> """
常用屬性
屬性 | 作用 |
---|---|
year | date對象表示的具體年份(實例化對象調(diào)用達到效果); |
month | date對象表示的具體月份(實例化對象調(diào)用達到效果); |
day | date對象表示的具體日(實例化對象調(diào)用達到效果); |
max | date類能夠表示的最大日期; |
min | date類能夠表示的最小日期; |
resolution | date類能夠表示的最小單位; |
常用方法
注意,以下方法如果可以返回新的對象,使用對象調(diào)用時,返回新的對象,原對象不變;如果根據(jù)對象值返回對應(yīng)的值,則使用類調(diào)用達不到目標效果;
方法 | 作用 |
---|---|
today() | 返回本地日期對象; |
fromtimestamp(time_stamp) | 給定時間戳返回日期對象; |
replace(y, m, d) | 給定年月日返回日期對象; |
timetuple() | 返回本地當(dāng)前時間元組time.struct_time對象; |
weekday() | 返回星期序號,星期一返回0; |
isoweekday() | 返回星期序號,星期一返回1; |
isocalendar() | 返回元組,表示日期的年份、第幾周、第幾周之后的第幾天; |
isoformat() | 返回時間字符串; |
strftime() | 格式化日期,參考time.strftime(); |
time類
time
類是datetime
模塊中專門用于描述時間的類,四個參數(shù):hour
、minute
、second
、microsecond
默認都為0。
datetime.time(hour=0, minute=0, second=0, microsecond=0)
from datetime import time time_0 = time() print(time_0) print(type(time_0)) """ 結(jié)果: 00:00:00 <class 'datetime.time'> """
time
的屬性和date
類的屬性方法基本相同,可以參考使用;
datetime類
相同于date
和time
兩個類的結(jié)合,使用基本相同;
timedelta類
timedelta
類用于時間運算,類的參數(shù)有datetime
模塊支持的所有時間單位,使用其它的時間和日期對象可以和timedelta
對象進行時間加減運算,注意在實例化時使用關(guān)鍵字傳參;
from datetime import datetime from datetime import timedelta # 日期對象 datetime_o = datetime(2000, 10, 30, 14, 40, 6) print(datetime_o) # ## 假設(shè)我們要計算這個時間5天4小時23分6秒之后的時間 # 實例化 5天4小時23分6秒 的timedelta對象 timedelta_o = timedelta(days=5, hours=4, minutes=23, seconds=6) # 將時間對象和timedelta對象相加 datetime_o += timedelta_o print(datetime_o) """ 結(jié)果: 2000-10-30 14:40:06 2000-11-04 19:03:12 """
到此這篇關(guān)于詳解Python常用標準庫之時間模塊time和datetime的文章就介紹到這了,更多相關(guān)Python time datetime內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django使用F方法更新一個對象多個對象字段的實現(xiàn)
這篇文章主要介紹了django使用F方法更新一個對象多個對象字段的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03實例講解Python腳本成為Windows中運行的exe文件
在本篇文章里小編給大家分享了關(guān)于Python腳本成為Windows中運行的exe文件的相關(guān)知識點內(nèi)容,有興趣的朋友們學(xué)習(xí)下。2019-01-01Python 面向?qū)ο箪o態(tài)方法、類方法、屬性方法知識點小結(jié)
這篇文章主要介紹了Python 面向?qū)ο箪o態(tài)方法、類方法、屬性方法,總結(jié)分析了Python 面向?qū)ο蟪绦蛟O(shè)計中靜態(tài)方法、類方法、屬性方法相關(guān)概念、知識點、操作技巧與使用注意事項,需要的朋友可以參考下2020-03-03計算機二級python學(xué)習(xí)教程(2) python語言基本語法元素
這篇文章主要為大家詳細介紹了計算機二級python學(xué)習(xí)教程的第2篇,Python語言基本語法元素,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05python 刪除系統(tǒng)中的文件(按時間,大小,擴展名)
這篇文章主要介紹了python 如何刪除系統(tǒng)中的文件,分別按時間,大小,擴展名刪除,滿足不同需求,感興趣的朋友可以了解下2020-11-11python調(diào)用golang中函數(shù)方法
由于simhash方法有多種實現(xiàn)方式,現(xiàn)python中simhash方法與golang中的不一樣,需要兩者代碼生成結(jié)果保持一致,故采用python中的代碼調(diào)用golang編譯的so文件來實現(xiàn),需要的朋友可以參考下2024-02-02