python 學習筆記 14 -- 常用的時間模塊之datetime

書接上文,前面我們講到《常用的時間模塊之time》,這次我們學習datetime -- 日期和時間值管理模塊


使用apihelper 查看datetime 模塊,我們可以看到簡單的幾項:
date       ---  日期對象,結構爲date(year, month, day)
time       ---  時間值對象,結構爲 time([hour[, minute[, second[, microsecond[, tzinfo]]]]])。時間對象所有的參數都是可選的。tzinfo 可以是None 或者是tzinfo子類的一個實例。 
datetime   ---  日期和時間管理對象,結構爲 datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])。 其中year, month 以及day 參數是必需的。而tzinfo 可以是None 或者是tzinfo子類的一個實例。
timedelta  ---  兩個datetime 值的差。用作datetime 對象之間的計算以及比較。
tzinfo     ---  時區信息對象的抽象基類
            

我們可以看到datetime 模塊下面還有好幾個具體的類,下面分別從這幾個類來分析datetime 模塊:

1. date

1.1 date 類簡介以及簡單使用

date 是一個日期對象類,它有year,month和day三個屬性。使用today()方法很容易創建一個表示當前日期的日期對象。當然,我們也可以手動指定年月日,從而直接使用datetime.date(year, month, day) 來創建一個日期對象,如:
    >>> da = datetime.date(1991, 1, 1)
    >>> da
    datetime.date(1991, 1, 1)
    >>> da.year                    # 還可以通過指定具體項獲取對應值

    1991


我們再來看看date 類的相關信息:
    >>> print datetime.date.resolution        # 日期對象的分辨率是一天
    1 day, 0:00:00
    >>> print datetime.date.min                # 日期對象最小值是1-1-1,下面會提到 toordinal 函數,它的返回值就是從這天計算的
    0001-01-01
    >>> print datetime.date.max                # 最大值

    9999-12-31


date 對象之間是可以計算的,算算你到這個世界多久了?
    >>> bron_day = datetime.date(1991, 1, 1)    # 指定生日
    >>> today = datetime.date.today()            # 獲取今天的date 信息
    >>> print today-bron_day                    
    8590 days, 0:00:00                            # date 對象之間直接相減,得到以日計算的差值
    >>> today < bron_day                        
    False                                        # 還可以直接對date 對象進行比較


1.2 date 類提供的方法

下面我們仍然使用apihelper (使用見《python 學習筆記 9 -- Python強大的自省簡析》)來查看date 類還提供了哪些強大的方法:

(1) today  

以當前時間獲取一個日期對象
    >>> today = datetime.date.today()
    >>> today
    datetime.date(2014, 7, 8)

(2) ctime  

將一個日期對象轉化爲ctime() 形式的字符串
    >>> date.date.ctime(today)
    'Tue Jul  8 00:00:00 2014'

(3) replace   

對於日期對象,支持使用replace 方法直接修改具體項
    >>> da = datetime.date(2008, 10, 1)
    >>> print da
    2008-10-01
    >>> print da.replace(2001, 1, 1)        # 不指定,可全部進行修改
    2001-01-01
    >>> print da.replace(year=2009, day=13)    # 符合python 的參數習慣,可以指定修改某一參數
    2009-10-13

(4) isoformat 

以ISO 8601 格式("YYYY-MM-DD")返回一個日期對象
    >>> datetime.date.isoformat(today)
    '2014-07-08'

(5) weekday 和 isoweekday

weekday   -- 返回日期對象是周幾。注意:返回值從0~6 ,也就是說Monday == 0 ... Sunday == 6。

isoweekday --返回日期對象是周幾,但是isoweekday 返回值與weekday的返回值不一樣,其返回值範圍爲1~7:Monday == 1 ... Sunday == 7。

    >>> time.ctime()
    'Wed Jul  9 11:24:58 2014'        # 今天是週三
    >>> today.weekday()
    2                                # 使用weekday 獲取的返回值是2,因爲它從0開始計數,週三對應2。
    >>> today.isoweekday()            # 使用isoweekday 獲取的是3,符合日常使用習慣。
    3

(6) isocalendar

返回一個3元元組,值分別表示(年,第幾周,周幾)
    >>> today.isocalendar()
    (2014, 28, 3)    

(7) strftime 

與time.strftime 類似,用於將時間對像進行格式化轉化
    >>> today.strftime('%Y-%m-%d %H:%M:%S')
    '2014-07-09 00:00:00'            # 至此,我們才發現默認使用 today = datetime.date.today() 獲取今天日期對象,只獲取了日期信息,而對應的時間默認使用了 00:00:00,後面我們會介紹使用 datetime 對象將日期對象和時間對像結合!

注:下面介紹的對象中都會涉及到 strftime 或 strptime, 其實用法都和前面 time 模塊中介紹的一樣,具體參數意義也請參見《python 學習筆記 13 -- 常用的時間模塊之time


(8) timetuple

時間結構體 struct_time 形式返回時間信息,與time.localtime()兼容:
    >>> today.timetuple()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=190, tm_isdst=-1)

(9) fromtimestamp

此函數能夠解析time.time()返回的浮點值,返回一個datetime.date 日期值,格式爲"datetime.date(2014, 7, 8)", 所以我們可以通過datetime.date.fromtimestamp(time.time()).year 來獲取年(月,日亦可!)
    >>> time.time()
    1404876430.573843
    >>> datetime.date.fromtimestamp(1404876430)
    datetime.date(2014, 7, 9)
    >>> datetime.date.fromtimestamp(1404876430.0)
    datetime.date(2014, 7, 9)
    >>> datetime.date.fromtimestamp(1404876430.0).year
    2014

(10)  toordinalfromordinal

toordinal -- 返回日期對象位於公曆的序數,也就是說返回值是“ 時間對象是從1年1月1日起的第幾天”(返回值是一個整數)。

fromordinal -- 上面的toordinal 會將一個日期對象經過計算,返回這個日期是1年1月1日開始的第幾天。而fromordinal 功能剛好與toordinal相反,它可以計算出一個給定的整形數對應的日期對象

    >>> today.toordinal()
    735423
    >>> datetime.date.fromordinal(735423)
    datetime.date(2014, 7, 9)


2. time

2.1 time 類簡介以及簡單使用

datetime 的 time類用來表示時間信息,如上面介紹的date 類,我們可以使用time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) 來初始化時間對象
我們再來看看time 類的相關信息:
    >>> print datetime.time.min            # 合法時間範圍爲00:00:00 ~ 23:59:59.999999
    00:00:00
    >>> print datetime.time.max
    23:59:59.999999
    >>> print datetime.time.resolution    # 分辨率限制爲微秒級

    0:00:00.000001


我們也可以直接指定項獲取其內容:
    >>> ti = datetime.time(11, 36, 0)
    >>> ti.hour
    11

2.2 time 類提供的方法

下面我們仍然使用apihelper來查看time 類提供了哪些強大的方法:

(1) isoformat 

以 ISO 8601 格式(HH:MM:SS[.mmmmmm][+HH:MM].)返回時間值

    >>> ti.isoformat()
    '15:10:20'

(2) replace

與上面的日期類中的replace 方法類似,用於替換日期對象中的值

    >>> ti = datetime.time(15, 10, 20)
    >>> ti.replace(hour = 12)
    datetime.time(12, 10, 20)

(3) strftime  

如同上面的strftime 方法,以自定義的格式打印信息

    >>> ti.strftime('%Y-%m-%d %H:%M:%S')
    '1900-01-01 15:10:20'        # 看來未指定年月日,系統默認是1900-01-01

其他還有三個方法: dst, tzname, utcoffset ,一般應該用不上,這裏就不介紹了!



3. datetime

3.1 datetime 類簡介以及簡單使用

使用datetime 類可以存儲由日期和時間分量構成的值。


我們先看看預定給datetime 類的一些細節:
    >>> print datetime.datetime.resolution        # 同time, datetime 的精度爲一微秒
    0:00:00.000001
    >>> print datetime.datetime.min                # datetime 最小值爲0001年1月1日的0時0分0秒,這也是公曆的起始
    0001-01-01 00:00:00
    >>> print datetime.datetime.max                # 最大值
    9999-12-31 23:59:59.999999

同上面date/time, datetime 也可以直接手動定義:" datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])" 其中year, month 以及day 參數是必需的。

    >>> datetime.datetime(2008, 11, 20, 10, 50)
    datetime.datetime(2008, 11, 20, 10, 50)
    >>> print datetime.datetime(2008, 11, 20, 10, 50).time()    # 可以直接使用time 和date 獲取datetime 的時間和日期信息。
    10:50:00
    >>> print datetime.datetime(2008, 11, 20, 10, 50).time().hour    # 想要獲取時間/日期信息下面的時分秒/年月日就要在使用time/date 之後再使用需要的項來獲取。
    10


對於datetime 的十幾種方法,我們按照官方手冊將其分爲“類方法”和“實例方法”兩個方面來講解:

3.2 類方法:

類方法可以理解成通過 datetime.datetime.**() 調用的方法,如:
    now = datetime.datetime.now()
=====================================================

(1) today, now 和 utcnow

 today      -- today 方法可以獲取當前日期和時間(沒有時區信息)等於datetime.datetime.fromtimestamp(time.time())
 now([tz])  -- 返回當前日期和時間,如果沒有使用tz 作爲參數,其結果與today方法一樣;如果有時區信息,則返回的時區對應的時間(注:這裏要求的tz 是tzinfo 類的一個實例而不是一個字符串)。
 utcnow     -- 方法與now 類似,只不過提供的是UTC 時間。(UTC,Coordinated Universal Time ,世界標準時間, now 得到的時間是根據UTC時間加上時區的)
    >>> datetime.datetime.now()
    datetime.datetime(2014, 7, 8, 20, 34, 59, 121292)
    >>> datetime.datetime.today()        # today 和now 獲取的時間一致
    datetime.datetime(2014, 7, 8, 20, 35, 0, 565851)
    >>> datetime.datetime.utcnow()        # UTC 時間當前爲12點,而我們北京時間處於東8區,加8個小時,剛好等於now/today顯示的20點
    datetime.datetime(2014, 7, 8, 12, 35, 6, 89866)

(2) fromtimestamp 和 utcfromtimestamp

 fromtimestamp(timestamp[, tz])  -- fromtimestamp 根據POSIX 的時間戳(比如time.time())返回一個時間信息。與now 比較接近,如果沒有攜帶'tz'參數,它會將時間戳轉化爲本地時間和日期;如果有時區信息'tz',返回的是該時區的時間信息。
 utcfromtimestamp(timestamp)     -- 將時間戳轉化爲UTC 時間

    >>> datetime.datetime.utcfromtimestamp(time.time())
    datetime.datetime(2014, 7, 9, 6, 42, 3, 395073)
    >>> datetime.datetime.fromtimestamp(time.time())        # 本地時間,CST 比UTC時間多8小時
    datetime.datetime(2014, 7, 9, 14, 42, 7, 528134)    
    >>> datetime.datetime.today()                            # 上面介紹today 時說了,today()的返回值與fromtimestamp(time.time())一樣
    datetime.datetime(2014, 7, 9, 14, 42, 19, 450996)        

(3) fromordinal

fromordinal -- 與下面要介紹的實例方法toordinal 相反,實例方法toordinal會將一個datetime 對象返回值爲自公曆1年1月1日起的第幾天,而fromordinal 將一個天數(整形)計算出來對應的哪年哪月哪日
    >>> now
    datetime.datetime(2014, 7, 8, 20, 41, 2, 882183)
    >>> datetime.datetime.toordinal(now)
    735422
    >>> datetime.datetime.fromordinal(735422)        # 因爲toordinal 計算的只是第幾天,未涉及到具體時間,所以fromordinal 轉化後的時間爲0:0:0
    datetime.datetime(2014, 7, 8, 0, 0)

(4) combine

conbine 方法可以將一個date 實例和一個time 實例結合創建一個datetime 實例。
    >>> today = datetime.date.today()
    >>> today.strftime('%Y-%m-%d %H:%M:%S')
    '2014-07-09 00:00:00'            # 使用 date.today() 只會接收今天的日期,不會接收時間信息,時間默認使用 00:00:00
    >>> now = datetime.time(12, 30, 00)
    >>> now.strftime('%Y-%m-%d %H:%M:%S')
    '1900-01-01 12:30:00'            # 使用time 設置時間後,日期默認使用 1900-01-01
    >>> print datetime.datetime.combine(today, now)
    '2014-07-09 12:30:00'            # 使用datetime 的combine 方法可以將上面的日期實例和時間實例集合爲一個datetime 實例。


(5) strptime

同前面介紹time 中的strptime一樣,strptime 可以將一個格式化打印的字符串整合成爲原來的datetime 對象

    >>> now = datetime.datetime.now()
    >>> now
    datetime.datetime(2014, 7, 9, 15, 54, 17, 742398)
    >>> now.strftime('%Y-%m-%d %H:%M:%S')        # 下面將要介紹的一個實例方法,其實和time.strftime 類似
    '2014-07-09 15:54:17'     # 此時是一個格式化打印的字符串\
    >>> datetime.datetime.strptime(now.strftime('%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S')
    datetime.datetime(2014, 7, 9, 15, 54, 17)             # 使用strptime 將字符串還原爲 datetime 對象


3.3 實例方法:

實例方法可以理解成datetime 實例/對象調用的方法,如:
    now = datetime.datetime.now()
    now.***();        ### 其中*** 對應的就是實例方法
其實也可以使用datetime.datetime.***(now)來調用。舉個例子:

    >>> now.date()    # date 就是下面要講的實例方法之一
    datetime.date(2014, 7, 9)
    >>> datetime.datetime.date(now)    # 實例方法也可以通過類似於類方法那麼調用,只不過需要實例/對象作爲參數
    datetime.date(2014, 7, 9)
既然放在實例方法一節,下面例子中都使用 now.***() 方式調用。
==============================================

(1)date   

返回datetime.datetime對象的日期值
    >>> now = datetime.datetime.now()
    >>> now.date()
    datetime.date(2014, 7, 9)

(2) time 和 timetz

 time       --將一個datetime.datetime 對象的時間值返回
 timetz     -- 使用相同的時間和時區返回time 對象
    >>> now.time()
    datetime.time(14, 48, 2, 224132)
    >>> now.timetz()
    datetime.time(14, 48, 2, 224132)

(3) replace   

可以指定修改域對datetime 實例進行修改
    >>> utcnow = datetime.datetime.utcnow()
    >>> utcnow
    datetime.datetime(2014, 7, 8, 12, 37, 21, 59472)
    >>> utcnow.replace(hour = 1)
    datetime.datetime(2014, 7, 8, 1, 37, 21, 59472)

(4) timetuple 和 utctimetuple

 timetuple  --將一個datetime.datetime 對象解析成一個struc_time結構體返回。(與time.localtime()的返回值類型一樣)
 utctimetuple  -- 與上面timetuple類似,返回UTC時間的解析結構體
    >>> now.timetuple()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=48, tm_sec=2, tm_wday=2, tm_yday=190, tm_isdst=-1)
    >>> now.utctimetuple()
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=48, tm_sec=2, tm_wday=2, tm_yday=190, tm_isdst=0)
    >>> time.localtime(time.time())            # 使用time.localtime 解析time()的浮點數得到的結果同timetuple 一樣,都是struct_time 結構的時間
    time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=51, tm_sec=12, tm_wday=2, tm_yday=190, tm_isdst=0)

(5) toordinal     

返回一個整數,代表datetime.datetime 對象是從第1年第1月第1天算起的第幾天。

(6) weekday 和 isoweekday

weekday    -- 返回datetime對象是周幾,但是對應的值從0~6: Monday == 0 ... Sunday == 6
isoweekday -- 返回datetime對象是周幾,對應的值從1~7: Monday == 1 ... Sunday == 7
    >>> now.ctime()                # 以ctime() 字符串形式打印datetime 對象的時間日期信息。下面會提到
    'Wed Jul  9 14:48:02 2014'        # 週三
    >>> now.weekday()    
    2                                # 週三使用weekday 返回2
    >>> now.isoweekday()    
    3                                # isoweekday 返回3


(7) isocalendar

返回一個三值的元組,格式爲(年,第幾周,周幾)
    >>> now.isocalendar()
    (2014, 28, 3)

(8) isoformat

以ISO 8601 格式(YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM])打印datetime.datetime對象。默認使用的間隔符是'T'.
    >>> datetime.datetime.isoformat(now)
    '2014-07-08T20:41:02.882183'

(9) ctime

ctime      -- 將datetime.datetime 對象解析成time.ctime 的字符串

(10) strftime

strftime   -- 同其他類一樣,datetime 可以通過strftime 進行格式化打印成你想要的格式。(默認是用的是ISO-8601 格式:YYYY-MM-DDTHH:MM:SS.mmmmmm)
    >>> now.strftime('%Y-%m-%d %H:%M:%S')
    '2014-07-09 14:48:02'

(11) 其他

上面還未涉及到這幾個函數astimezone, utcoffset, dst, tzname,都是與時區相關,一般涉及不到,此處不追逐。



4. timedelta

4.1 timedelta 類簡介以及簡單使用

    datetime 對象之間可以使用算術運算,或者結合一個datetime 和一個timedelta ,可以用來計算過去或將來的一些日期。兩個日期相減可以生成一個timedelta, 還可以對某個日期與一個timedelta 計算來得出另一個日期。所以可以理解成兩個datetime 的中間變量,可以用於計算和比較。
來看看timedelta 的精度以及範圍:
    >>> print datetime.timedelta.max
    999999999 days, 23:59:59.999999
    >>> print datetime.timedelta.min
    -999999999 days, 0:00:00
    >>> print datetime.timedelta.resolution        # 精度爲1微秒
    0:00:00.000001

timedelta 的內部值按日、秒和毫秒存儲:
    >>> td = datetime.timedelta(microseconds = 1); print "%s -- %r" %(td, td)
    0:00:00.000001 -- datetime.timedelta(0, 0, 1)
    >>> td = datetime.timedelta(milliseconds = 1); print "%s -- %r" %(td, td)
    0:00:00.001000 -- datetime.timedelta(0, 0, 1000)
    >>> td = datetime.timedelta(seconds = 1); print "%s -- %r" %(td, td)
    0:00:01 -- datetime.timedelta(0, 1)
    >>> td = datetime.timedelta(minutes = 1); print "%s -- %r" %(td, td)
    0:01:00 -- datetime.timedelta(0, 60)
    >>> td = datetime.timedelta(hours = 1); print "%s -- %r" %(td, td)
    1:00:00 -- datetime.timedelta(0, 3600)
    >>> td = datetime.timedelta(days = 1); print "%s -- %r" %(td, td)
    1 day, 0:00:00 -- datetime.timedelta(1)
    >>> td = datetime.timedelta(weeks = 1); print "%s -- %r" %(td, td)
    7 days, 0:00:00 -- datetime.timedelta(7)


4.2 timedelta 類提供的方法

    因爲timedelta 只是一個用於計算的中間量,所以並沒有提供很多方法,用apihelper 可以看到只提供一個方法total_seconds 用以返回一個timedelta 完整時間段的所有秒數:
    >>> td = datetime.timedelta(hours = 1); print td.total_seconds()
    3600.0

4.3 使用timedelta 計算

    >>> one_day = datetime.timedelta(days = 1);   # one_day 是一個定義爲1天的timedelta 實例
    >>> today = datetime.date.today()                   # today 是date 實例
    >>> tomorrow = today + one_day              # 直接使用timedelta 實例與datetime 的date 實例進行計算
    >>> yestoday = today - one_day
    >>> today
    datetime.date(2014, 7, 8)
    >>> tomorrow
    datetime.date(2014, 7, 9)
    >>> yestoday
    datetime.date(2014, 7, 7)
    >>> tomorrow - yestoday            # 兩個date 實例也可以計算
    datetime.timedelta(2)
    >>> print tomorrow - yestoday
    2 days, 0:00:00

4.4 使用timedelta 比較

    >>> today > yestoday               # date 實例可以直接比較
    True
    >>> tomorrow == yestoday
    False


寫到這,感覺該有的都有了,而且本文中有大量的例子,其實如果你不練習,還是難以記住這麼多知識點,只要親自寫代碼試驗了,這些還是很好記很好理解的。比如說你可以做一個小鬧鐘提示什麼的。

==================================
說在最後的話:
其實悉心的你可以發現,datetime 類中還有 tzinfo 沒有介紹,但是~~說實話,沒怎麼看懂,而且應該也用不上。此處不再贅述,還望諒解。


=======================================

注:本文介紹了 datetime 模塊,其他的時間模塊還有 time 和calendar 將於本系列其他文章。絕大部分內容都取自《Python 標準庫》以及Python 官方文檔, 限於個人能力有限,如有解釋錯誤或者不當,敬請提出~

注: 轉載註明出處: http://blog.csdn.net/longerzone



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章