1. 程式人生 > >python datetime 模組

python datetime 模組

time 模組用於取得 Unix 紀元時間戳,並加以處理。但是,如果以更方便的格式顯示日期,或對日期進行算術運算(例如,搞清楚 205 天前是什麼日期,或 123天后是什麼日期),就應該使用 datetime 模組。datetime 模組有自己的 datetime 資料型別。 datetime 值表示一個特定的時刻。 在互動式環境中輸入以下程式碼:

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2015, 2, 27, 11, 10, 49, 55, 53)
>>> dt = datetime.datetime(2015, 10, 21, 16, 29, 0)
>>> dt.year, dt.month, dt.day
(2015, 10, 21)
>>> dt.hour, dt.minute, dt.second
(16, 29, 0)

呼叫 datetime.datetime.now()返回一個 datetime 物件,表示當前的日期和時間,根據你的計算機的時鐘。這個物件包含當前時刻的年、月、日、時、分、秒和微秒。也可以利用 datetime.datetime()函式,向它傳入代表年、月、日、時、分、秒的整數,得到特定時刻的 datetime 物件。這些整數將儲存在 datetime 物件的 year、month、 day、 hour、 minute 和 second屬性中。Unix 紀元時間戳可以通過 datetime.datetime.fromtimestamp(),轉換為 datetime物件。 datetime 物件的日期和時間將根據本地時區轉換。在互動式環境中輸入以下程式碼:

>>> datetime.datetime.fromtimestamp(1000000)
datetime.datetime(1970, 1, 12, 5, 46, 40)
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2015, 2, 27, 11, 13, 0, 604980)

呼叫 datetime.datetime.fromtimestamp()並傳入 1000000,返回一個 datetime 物件, 表示 Unix 紀元後 1000000 秒的時刻。傳入 time.time(),即當前時刻的 Unix 紀元時間戳,則返回當前時刻的 datetime 物件。因此,表示式 datetime.datetime.now()和 datetime.datetime.fromtimestamp(time.time())做的事情相同,它們都返回當前時刻的 datetime 物件。datetime 物件可以用比較操作符進行比較,弄清楚誰在前面。後面的 datetime 物件是“更大”的值。在互動式環境中輸入以下程式碼:

>>> halloween2015 = datetime.datetime(2015, 10, 31, 0, 0, 0)
>>> newyears2016 = datetime.datetime(2016, 1, 1, 0, 0, 0)
>>> oct31_2015 = datetime.datetime(2015, 10, 31, 0, 0, 0)
>>> halloween2015 == oct31_2015
True
>>> halloween2015 > newyears2016
False
>>> newyears2016 > halloween2015
True
>>> newyears2016 != oct31_2015
True

為 2015 年 10 月 31 日的第一個時刻(午夜)建立一個 datetime 物件,將它儲存在 halloween2015 中。為 2016 年 1 月 1 日的第一個時刻建立一個 datetime 物件,將它儲存在 newyears2016 中。然後,為 2015 年 10 月 31 日的午夜建立另一個物件, 將它儲存在 oct31_2015 中。比較 halloween2015 和 oct31_2015,它們是相等的。比較 newyears2016 和 halloween2015, newyears2016 大於(晚於) halloween2015 。  

timedelta 資料型別 datetime 模組還提供了 timedelta 資料型別,它表示一段時間,而不是一個時刻。在互動式環境中輸入以下程式碼:

>>> delta = datetime.timedelta(days=11, hours=10, minutes=9, seconds=8)
>>> delta.days, delta.seconds, delta.microseconds
(11, 36548, 0)
>>> delta.total_seconds()
986948.0
>>> str(delta)
'11 days, 10:09:08'

建立 timedelta 物件,就用 datetime.timedelta()函式。 datetime.timedelta()函式接受關鍵字引數 weeks、 days、 hours、 minutes、 seconds、 milliseconds 和 microseconds。沒有 month 和 year 關鍵字引數,因為“月”和“年”是可變的時間,依賴於特定月份或年份。 timedelta 物件擁有的總時間以天、秒、微秒來表示。這些數字分別儲存在 days、 seconds 和 microseconds 屬性中。 total_seconds()方法返回只以秒錶示的時間。將一個 timedelta 物件傳入 str(),將返回格式良好的、人類可讀的字串表示。在這個例子中,我們將關鍵字引數傳入 datetime.delta(),指定 11 天、 10 小時、9 分和 8 秒的時間,將返回的 timedelta 物件儲存在 delta 中。該 timedelta 物件的days 屬性為 11, seconds 屬性為 36548(10 小時、 9 分鐘、 8 秒,以秒錶示)。呼叫 total_seconds()告訴我們, 11 天、 10 小時、 9 分和 8 秒是 986948 秒。最後,將這個timedelta 物件傳入 str(),返回一個字串,明確解釋了這段時間。算術運算子可以用於對 datetime 值進行日期運算。例如,要計算今天之後 1000天的日期,在互動式環境中輸入以下程式碼:

>>> dt = datetime.datetime.now()
>>> dt
datetime.datetime(2015, 2, 27, 18, 38, 50, 636181)
>>> thousandDays = datetime.timedelta(days=1000)
>>> dt + thousandDays
datetime.datetime(2017, 11, 23, 18, 38, 50, 636181)

首先,生成表示當前時刻的 datetime 物件,儲存在 dt 中。然後生成一個 timedelta物件,表示 1000 天,儲存在 thousandDays 中。 dt 與 thousandDays 相加,得到一個datetime 物件,表示現在之後的 1000 天。 Python 將完成日期運算,弄清楚 2015 年2 月 27 日之後的 1000 天,將是 2017 年 11 月 23 日。這很有用,因為如果要從一個給定的日期計算 1000 天之後,需要記住每個月有多少天,閏年的因素和其他棘手的細節。 datetime 模組為你處理所有這些問題。利用+和-運算子, timedelta 物件與 datetime 物件或其他 timedelta 物件相加或相減。利用*和/運算子, timedelta 物件可以乘以或除以整數或浮點數。在互動式環境 中輸入以下程式碼:

>>> oct21st = datetime.datetime(2015, 10, 21, 16, 29, 0)
>>> aboutThirtyYears = datetime.timedelta(days=365 * 30)
>>> oct21st
datetime.datetime(2015, 10, 21, 16, 29)
>>> oct21st - aboutThirtyYears
datetime.datetime(1985, 10, 28, 16, 29)
>>> oct21st - (2 * aboutThirtyYears)
datetime.datetime(1955, 11, 5, 16, 29)

這裡,我們生成了一個 DateTime 物件,表示 2015 年 10 月 21 日,以及一個timedelta 物件,表示大約 30 年的時間(我們假設每年為 365 天) 。從 oct21st 中減去 aboutThirtyYears,我們就得到一個 datetime 物件,表示 2015 年 10 月 21 日前 30年的一天。從 oct21st 中減去 2 * aboutThirtyYears,得到一個 datetime 物件,表示 2015年 10 月 21 日之前 60 年的一天。  

暫停直至特定日期 time.sleep()方法可以暫停程式若干秒。利用一個 while 迴圈,可以讓程式暫停,直到一個特定的日期。例如,下面的程式碼會繼續迴圈,直到 2016 年萬聖節:

import datetime
import time
halloween2016 = datetime.datetime(2016, 10, 31, 0, 0, 0)
while datetime.datetime.now() < halloween2016:
    time.sleep(1)

time.sleep(1)呼叫將暫停你的 Python 程式,這樣計算機不會浪費 CPU 處理週期,一遍又一遍地檢查時間。相反, while 迴圈只是每秒檢查一次,在 2016 年萬聖節(或你程式設計讓它停止的時間)後繼續執行後面的程式。  

將 datetime 物件轉換為字串 Unix 紀元時間戳和 datetime 物件對人類來說都不是很友好可讀。利用 strftime()方法,可以將 datetime 物件顯示為字串。(strftime()函式名中的 f 表示格式, format)。該的 strftime()方法使用的指令類似於 Python 的字串格式化。表 15-1 列出了完整的 strftime()指令。

向 strftime()傳入一個定製的格式字串,其中包含格式化指定(以及任何需要的斜線、冒號等), strftime()將返回一個格式化的字串,表示 datetime 物件的資訊。在互動式環境中輸入以下程式碼:

>>> oct21st = datetime.datetime(2015, 10, 21, 16, 29, 0)
>>> oct21st.strftime('%Y/%m/%d %H:%M:%S')
'2015/10/21 16:29:00'
>>> oct21st.strftime('%I:%M %p')
'04:29 PM'
>>> oct21st.strftime("%B of '%y")
"October of '15

這裡,我們有一個 datetime 物件,表示 2015 年 10 月 21 日下午 4 點 29 分,儲存在 oct21st 中。向 strftime()傳入定製的格式字串'%Y/%m/%d %H:%M:%S,返回一個字串,包含以斜槓分隔的 2015、 10 和 21,以冒號分隔的 16、 29 和 00。傳入'%I:%M% p'則返回'04:29 PM',傳入"%B of '%y"則返回"October of '15"。請注意,strftime()不是以 datetime.datetime 開始。  

將字串轉換成 datetime 物件 如果有一個字串的日期資訊,如'2015/10/21 16:29:00'或'October 21, 2015',需要將它轉換為 datetime 物件,就用 datetime.datetime.strptime()函式。 strptime()函式與strftime()方法相反。定製的格式字串使用相同的指令,像 strftime()一樣。必須將格式字串傳入 strptime(),這樣它就知道如何解析和理解日期字串(strptime()函式名中 p 表示解析, parse)。在互動式環境中輸入以下程式碼:

>>> datetime.datetime.strptime('October 21, 2015', '%B %d, %Y')
datetime.datetime(2015, 10, 21, 0, 0)
>>> datetime.datetime.strptime('2015/10/21 16:29:00', '%Y/%m/%d %H:%M:%S')
datetime.datetime(2015, 10, 21, 16, 29)
>>> datetime.datetime.strptime("October of '15", "%B of '%y")
datetime.datetime(2015, 10, 1, 0, 0)
>>> datetime.datetime.strptime("November of '63", "%B of '%y")
datetime.datetime(2063, 11, 1, 0, 0)

要從字串'October 21, 2015'取得一個 datetime 物件,將'October 21, 2015'作為第一個引數傳遞給 strptime(),並將對應於'October 21, 2015' 的定製格式字串作為第二個引數。帶有日期資訊的字串必須準確匹配定製的格式字串,否則 Python將丟擲 ValueError 異常。