python中處理時間的模塊有三個,datetime, time,calendar,融匯貫通三個模塊,才能爲所欲爲地用python處理時間。本文就是爲此而寫,文章着重點在於梳理出三個模塊的設計脈絡,便於你們記憶裏面的api。在須要的時候可以去查找相應的方法。但因爲calendar模塊使用很少,限於篇幅,本文沒有涉及。python
datetime模塊主要是用來表示日期的,就是咱們常說的年月日時分秒,calendar模塊主要是用來表示年月日,是星期幾之類的信息,time模塊主要側重點在時分秒,粗略從功能來看,咱們能夠認爲三者是一個互補的關係,各自專一一塊。方便用戶依據不一樣的使用目的選用趁手的模塊。linux
爲了學習time模塊,咱們須要先知道幾個與時間相關的概念:api
假設咱們要將時間表示成毫秒數,比方說1000000毫秒,那有一個問題必須解決,這個1000000毫秒的起點是什麼時間,也就是咱們的時間基準點是什麼時間?比如我說你身高1.8米,那這個身高是指相對於你站立的地面說的。這個時間基準點就是epoch,在Unix系統中,這個基準點就是1970年1月1日0點整那個時間點。app
上面咱們說epoch表示1970年的起始點,那這個1970年又是相對於哪一個基準時間呢?通常來講,就是相對於格林尼治時間,也叫作GMT(Greenwich Mean Time)時間,還叫作UTC(Coordinated Universal Time),爲啥一個時間基準有兩個名字?歷史上,先有的GMT,後有的UTC.ide
UTC是咱們如今用的時間標準,GMT是老的時間計量標準。UTC是根據原子鐘來計算時間,而GMT是根據地球的自轉和公轉來計算時間。函數
因此,能夠認爲UTC是真正的基準時間,GMT相對UTC的誤差爲0。學習
在實際中,咱們的計算機中有一個硬件模塊RCT,裏面會實時記錄UTC 時間,該模塊有單獨的電池供電,即便關機也不影響。spa
有了epoch這個時間基準,又有了UTC這個基準的基準,咱們就能夠精確地表示一個時間了。設計
儘管咱們已經能夠精確地表示一個時間,不少狀況下,咱們仍是要根據地區實際狀況對時間進行一個調整,最多見的就是時區,tzone,相信你們都比較熟悉。orm
此時,當咱們說5點5分這個時間時,還需加上是哪一個時區的5點5分才能精確說明一個時間。
另一個對時間作出調整的就是DST.
DST 全稱是Daylight Saving Time,是說,爲了充分利用日光,減小用電,人爲地對時間作出一個調整,這取決於不一樣國家和地區的政策法規。好比說,假設你冬天7點天亮起牀,但夏天6點天亮,那麼在夏天到來時人爲將時間加1個小時,這樣就可讓你仍是以爲7點起牀,但其實是提早一個小時了。
那麼,好奇的咱們,必定要問一問,python是如何知道tzone和DST這兩個的值呢?答案是經過環境變量。
這裏咱們只以linux爲例來講明一下。
在linux中有TZ環境變量,其值相似這樣:
CST+08EDT,M4.1.0,M10.5.0,這個字符串能夠作以下解讀,用空格分開他們,分紅三部分
CST+08 EDT, M4.1.0,M10.5.0
第一部分中的CST表示時區的名字,即China Standard Time,也就是咱們說的北京時間,+8表示北京時間加上8小時就是UTC時間
第二部分EDT表示DST的名字,咱們說DST是因各個國家地區的政策法規不一樣而不一樣的,EDT後面也能夠像CST後面同樣加一個時間調整值,但因爲咱們國內只在86年到92年實行過一段時間DST,如今已經廢止,因此後面不用加調整時間。
第三部分表示的是實行DST的開始和結束時間,咱們就不細解讀了。
time模塊中獲取時間的基本方法是
t = time.time()
它返回的是從epoch到如今的秒數(用浮點數表示),用的是UTC時間。
咱們天然而然地想把這個秒數轉爲年月日時分秒的形式,而這種轉換又分兩種,一種仍是用UTC時間,一種用咱們所在時區進行調整後的時間。
time模塊給咱們提供了兩個方法,
time. gmtime(t)
time.localtime(t)
兩者都返回一個類struct_time的實例,該實例具備以下屬性:
相比用秒數表示的時間,這樣的表示更適合咱們理解。
這兩個函數若是調用時不傳參數,它們內部會調用time.time(),並用返回的秒數作轉換。
相反的,python一樣提供了將這兩種struct_time轉爲秒數的方法。
calendar.timegm()方法用來把UTC的struct_time(gmtime的返回對象)轉爲從epoch開始的秒數
time.mktime()用來把用時區調整過的struct_time(即localtime的返回對象)對象轉爲從epoch開始的秒數
也就是說mktime方法會先找到系統中的時區和DST信息,並利用這個信息對struct_time進行調整後再換算成秒數。
另外一種常見的需求是在時間和表示時間的字符串之間進行轉換。
time模塊中的strftime和strptime就是作這個用的。
看名字你們就應該知道它們的含義,
strftime 即 string format time,用來將時間格式化成字符串
strptime 即string parse time,用來將字符串解析成時間。
須要注意的是,這裏的時間都是struct_time對象。
關於怎麼格式化時間,是很簡單的知識,這裏就借用官網文檔的內容了。
除了這兩個函數,time模塊中還提供了兩個簡便方法,來幫助將時間轉爲字符串
asctime用來將一個struct_time對象轉爲標準24字符的字符串,以下所示:
Sun Jun 20 23:21:05 1993
ctime方法與asctime做用相同,只不過它接收的是秒數,在內部,會先把秒數經過localtime轉爲struct_time,再日後就與asctime同樣了。
以上就是time模塊的核心內容,我嘗試用一個口訣幫助記憶這些API
time點time得秒數
傳入gm, local time得struct_time
要想變回原秒數
你得傳回calendar.timegm和time. mktime
string f和string p
格式化時間靠哥倆
你要仍是嫌費事
asctime ,ctime來助力
專門幫你轉字符串
前者接收struct_time
後者專門處理秒數
分工合做不費力
學好time模塊基本功
作個時間的明白人!
下面,咱們要開始學習datetime模塊。
time模塊解決了時間的獲取和表示,datetime模塊則進一步解決了快速獲取並操做時間中的年月日時分秒信息的能力。
簡單說,該模塊核心的類就三個,date類表示年月日,time類表示時分秒毫秒,這裏不要和time模塊搞混淆了。一句順口溜能夠幫助記清這個狀況:
time裏面沒time
藏在datetime裏
編的是否是不咋地?嗯,我也這麼以爲。
datetime類就是date和time的組合。
有一點須要提早說明一下,time類和datetime類都有一個屬性,它的值是一個tzinfo對象,裏面包含了該time或者datetime的時區信息,通常稱這個time或者datetime對象是aware的,它可以準確換算成自epoch開始的秒數。
若是該屬性設置爲None,那麼,這時的time對象或者datetime對象就沒有時區信息,具體它表示的是local time仍是utc time,須要咱們本身在程序中去決定。
這裏咱們所說的local time是指咱們所在時區的時間, utc time指的就是國際標準時間,也就是格林尼治時間。下文同。
請記住一點,date中是沒有時區信息的。
建立datetime對象,我最經常使用的辦法以下
dt=datetime.datetime.fromtimestamp(time.time())
以上,time.time()得到自epoch開始的秒數,fromtimestamp方法會將這個秒數轉變成一個datetime對象。
這裏有一個問題,這個datetime對象到底是utc的仍是local的?
答案是local的,這是該方法的默認行爲。若是你在fromtimestamp方法中傳入一個表示時區的參數,即tzinfo對象,就會按傳入的時區信息進行轉換。
得到表示當前local時間的datetime對象,還有兩個簡便方法
datetime. datetime. now()
datetime. datetime. today()
以上咱們獲得的都是local的datetime對象,如何得到utc的datetime對象呢?有兩個辦法
datetime. datetime. utcfromtimestamp()
datetime. datetime. utcnow()
咱們還能夠從字符串中建立datetime對象,
方法爲datetime.striptime(date_string, format)
其內部仍是先調用的time模塊中的striptime方法,獲取struct_time對象,再利用struct_time對象中的年月日時分秒信息構建datetime對象。
一樣的,datetime類也提供了strftime(),asctime(),ctime()方法,相信不說你也知道是作什麼的了。
datetime類還提供了一個combine方法,用來將一個date對象和一個time對象組合成一個datetime對象。
須要注意的是,datetime模塊中出現timestamp時,通常可將其理解成time.time()返回的秒數
date對象的建立和datetime很是類似,
datetime. date. today()
datetime.date.fromtimestamp()均可以建立一個date對象。
固然,你也能夠經過構造方法傳入年月日來建立date對象。
相比之下,time對象的建立就頗有限,只能經過
datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]])
這個方法建立。
在實際使用中,咱們有一大塊需求就是對日期進行比較和加減運算。得益於python的操做符重載能力,python中能夠方便地對
date對象之間,或者datetime對象之間進行小於(<)比較和減法(-)操做。
注意,這裏僅限於同類對象之間,並且,不包括time對象之間。
兩個date對象做減,或者兩個datetime對象之間做減,差值用一個timedelta對象表示。
同理,一個date 對象或者datetime對象也能夠加或者減一個timedelta對象。
一個timedelta對象含有三個屬性:days,seconds, microseconds,days屬性能夠取負值,另外兩個屬性都只能是正值。
你能夠用total_seconds()方法得到一個timedelta對象的秒數表示。
兩個timedelta對象之間可加,可減,但不能作大小比較,由於這樣沒什麼意義。
一個timedelta對象還能夠與整數相乘,或經過//操做與一個整數相除。
還能夠取反,或者用abs函數得到絕對值
本文的目的不在於詳細說明python處理時間日期的api如何使用,而是想經過一個概覽的形式,讓你們抓住time和datetime模塊的設計結構,從而可以清楚這些模塊提供了哪些能力,在須要的時候可以想起來去用,至於查詳細的api,應該是能夠輕鬆解決的。