前言
在開發工作中,我們經常需要用到日期與時間,如:
Python中提供了多個用于對日期和時間進行操作的內置模塊:time模塊、datetime模塊和calendar模塊。其中time模塊是通過調用C庫實現的,所以有些方法在某些平臺上可能無法調用,但是其提供的大部分接口與C標準庫time.h基本一致。time模塊相比,datetime模塊提供的接口更直觀、易用,功能也更加強大。
一、相關術語的解釋
二、時間的表現形式
常見的時間表示形式為:
Python中還有其它的時間表示形式:
關于datetime模塊的datetime類會在下面做詳細講解,這里簡單說下time.struct_time。
time.struct_time包含如下屬性:
| 下標/索引 | 屬性名稱 | 描述 |
|---|---|---|
| 0 | tm_year | 年份,如 2017 |
| 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 |
屬性值的獲取方式有兩種:
需要說明的是struct_time實例的各個屬性都是只讀的,不可修改。
三、 time模塊
time模塊主要用于時間訪問和轉換,這個模塊提供了各種與時間相關的函數。
1. 函數列表
| 方法/屬性 | 描述 |
|---|---|
| time.altzone | 返回與utc時間的時間差,以秒為單位(西區該值為正,東區該值為負)。其表示的是本地DST 時區的偏移量,只有daylight非0時才使用。 |
| time.clock() | 返回當前進程所消耗的處理器運行時間秒數(不包括sleep時間),值為小數;該方法Python3.3改成了time.process_time() |
| time.asctime([t]) | 將一個tuple或struct_time形式的時間(可以通過gmtime()和localtime()方法獲取)轉換為一個24個字符的時間字符串,格式為: "Fri Aug 19 11:14:16 2016"。如果參數t未提供,則取localtime()的返回值作為參數。 |
| time.ctime([secs]) | 功能同上,將一個秒數時間戳表示的時間轉換為一個表示當前本地時間的字符串。如果參數secs沒有提供或值為None,則取time()方法的返回值作為默認值。ctime(secs)等價于asctime(localtime(secs)) |
| time.time() | 返回時間戳(自1970-1-1 0:00:00 至今所經歷的秒數) |
| time.localtime([secs]) | 返回以指定時間戳對應的本地時間的 struct_time對象(可以通過下標,也可以通過 .屬性名 的方式來引用內部屬性)格式 |
| time.localtime(time.time() + n*3600) | 返回n個小時后本地時間的 struct_time對象格式(可以用來實現類似crontab的功能) |
| time.gmtime([secs]) | 返回指定時間戳對應的utc時間的 struct_time對象格式(與當前本地時間差8個小時) |
| time.gmtime(time.time() + n*3600) | 返回n個小時后utc時間的 struct_time對象(可以通過 .屬性名 的方式來引用內部屬性)格式 |
| time.strptime(time_str, time_format_str) | 將時間字符串轉換為struct_time時間對象,如:time.strptime('2017-01-13 17:07', '%Y-%m-%d %H:%M') |
| time.mktime(struct_time_instance) | 將struct_time對象實例轉換成時間戳 |
| time.strftime(time_format_str, struct_time_instance) | 將struct_time對象實例轉換成字符串 |
2. 練習
獲取時間戳格式的時間
>>> time.time()1486188022.862
獲取struct_time格式的時間
>>> time.localtime()time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=2, tm_sec=34, tm_wday=5, tm_yday=35, tm_isdst=0)>>> time.gmtime()time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=6, tm_min=2, tm_sec=56, tm_wday=5, tm_yday=35, tm_isdst=0)
獲取字符串格式的時間
>>> time.ctime()'Sat Feb 04 14:06:42 2017'>>> time.asctime()'Sat Feb 04 14:06:47 2017'
時間戳格式轉struct_time格式時間
>>> t1 = time.time()>>> print(t1)1486188476.9>>> t2 = time.localtime(t1)>>> print(t2)time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=7, tm_sec=56, tm_wday=5, tm_yday=35, tm_isdst=0)>>> t3 = time.gmtime(t1)>>> print(t3)time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=6, tm_min=7, tm_sec=56, tm_wday=5, tm_yday=35, tm_isdst=0)>>>
字符串格式轉struct_time格式時間
>>> time.strptime('Sat Feb 04 14:06:42 2017')time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=6, tm_sec=42, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> time.strptime('Sat Feb 04 14:06:42 2017', '%a %b %d %H:%M:%S %Y')time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=6, tm_sec=42, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> time.strptime('2017-02-04 14:12', '%Y-%m-%d %H:%M')time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=12, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> time.strptime('2017/02/04 14:12', '%Y/%m/%d %H:%M')time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=12, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> time.strptime('201702041412', '%Y%m%d%H%M')time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=14, tm_min=12, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=-1)struct_time格式轉字符串格式時間
>>> time.strftime('%Y-%m-%d %H:%M', time.localtime())'2017-02-04 14:19'struct_time格式轉時間戳格式時間>>> time.mktime(time.localtime())1486189282.03. 時間格式轉換
時間戳格式的時間 與 字符串格式的時間 雖然可以通過ctime([secs])方法進行轉換,但是字符串格式不太適應中國國情。因此,整體而言,它們 不能直接進行轉換,需要通過struct_time作為中介,轉換關系如下:

說明:上面的 '%H:%M:%S' 可以直接用 '%X' 代替。
四、 datetime模塊
datetime模塊提供了處理日期和時間的類,既有簡單的方式,又有復雜的方式。它雖然支持日期和時間算法,但其實現的重點是為輸出格式化和操作提供高效的屬性提取功能。
1. datetime模塊中定義的類
datetime模塊定義了以下幾個類:
| 類名稱 | 描述 |
|---|---|
| datetime.date | 表示日期,常用的屬性有:year, month和day |
| datetime.time | 表示時間,常用屬性有:hour, minute, second, microsecond |
| datetime.datetime | 表示日期時間 |
| datetime.timedelta | 表示兩個date、time、datetime實例之間的時間間隔,分辨率(最小單位)可達到微秒 |
| datetime.tzinfo | 時區相關信息對象的抽象基類。它們由datetime和time類使用,以提供自定義時間的而調整。 |
| datetime.timezone | Python 3.2中新增的功能,實現tzinfo抽象基類的類,表示與UTC的固定偏移量 |
需要說明的是:這些類的對象都是不可變的。
類之間的關系:
object date datetime time timedelta tzinfo timezone
2. datetime模塊中定義的常量
| 常量名稱 | 描述 |
|---|---|
| datetime.MINYEAR | datetime.date或datetime.datetime對象所允許的年份的最小值,值為1 |
| datetime.MAXYEAR | datetime.date或datetime.datetime對象所允許的年份的最大值,只為9999 |
3. datetime.date類
datetime.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)功能相同 |
實例
>>> import time>>> from datetime import date>>>>>> date.maxdatetime.date(9999, 12, 31)>>> date.mindatetime.date(1, 1, 1)>>> date.resolutiondatetime.timedelta(1)>>> date.today()datetime.date(2017, 2, 4)>>> date.fromtimestamp(time.time())datetime.date(2017, 2, 4)>>>>>> d = date.today()>>> d.year2017>>> d.month2>>> d.day4>>> d.replace(2016)datetime.date(2016, 2, 4)>>> d.replace(2016, 3)>>> d.replace(2016, 3, 2)datetime.date(2016, 3, 2)>>> d.timetuple()time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> d.toordinal()736364>>> d.weekday()5>>> d.isoweekday()6>>> d.isocalendar()(2017, 5, 6)>>> d.isoformat()'2017-02-04'>>> d.ctime()'Sat Feb 4 00:00:00 2017'>>> d.strftime('%Y/%m/%d')'2017/02/04'4. datetime.time類
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)功能相同 |
實例
>>> from datetime import time>>>>>> time.maxdatetime.time(23, 59, 59, 999999)>>> time.mindatetime.time(0, 0)>>> time.resolutiondatetime.timedelta(0, 0, 1)>>>>>> t = time(20, 5, 40, 8888)>>> t.hour20>>> t.minute5>>> t.second40>>> t.microsecond8888>>> t.tzinfo>>>>>> t.replace(21)datetime.time(21, 5, 40, 8888)>>> t.isoformat()'20:05:40.008888'>>> t.strftime('%H%M%S')'200540'>>> t.strftime('%H%M%S.%f')'200540.008888'5. datetime.datetime類
datetime類的定義
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) | 返回指定格式的時間字符串 |
實例
>>> from datetime import datetime, timezone>>>>>> datetime.today()datetime.datetime(2017, 2, 4, 20, 44, 40, 556318)>>> datetime.now()datetime.datetime(2017, 2, 4, 20, 44, 56, 572615)>>> datetime.now(timezone.utc)datetime.datetime(2017, 2, 4, 12, 45, 22, 881694, tzinfo=datetime.timezone.utc)>>> datetime.utcnow()datetime.datetime(2017, 2, 4, 12, 45, 52, 812508)>>> import time>>> datetime.fromtimestamp(time.time())datetime.datetime(2017, 2, 4, 20, 46, 41, 97578)>>> datetime.utcfromtimestamp(time.time())datetime.datetime(2017, 2, 4, 12, 46, 56, 989413)>>> datetime.combine(date(2017, 2, 4), t)datetime.datetime(2017, 2, 4, 20, 5, 40, 8888)>>> datetime.strptime('2017/02/04 20:49', '%Y/%m/%d %H:%M')datetime.datetime(2017, 2, 4, 20, 49)>>> dt = datetime.now()>>> dtdatetime.datetime(2017, 2, 4, 20, 57, 0, 621378)>>> dt.year2017>>> dt.month2>>> dt.day4>>> dt.hour20>>> dt.minute57>>> dt.second0>>> dt.microsecond621378>>> dt.tzinfo>>> dt.timestamp()1486213020.621378>>> dt.date()datetime.date(2017, 2, 4)>>> dt.time()datetime.time(20, 57, 0, 621378)>>> dt.timetz()datetime.time(20, 57, 0, 621378)>>> dt.replace()datetime.datetime(2017, 2, 4, 20, 57, 0, 621378)>>> dt.replace(2016)datetime.datetime(2016, 2, 4, 20, 57, 0, 621378)>>> dt.timetuple()time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=20, tm_min=57, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=-1)>>> dt.utctimetuple()time.struct_time(tm_year=2017, tm_mon=2, tm_mday=4, tm_hour=20, tm_min=57, tm_sec=0, tm_wday=5, tm_yday=35, tm_isdst=0)>>> dt.toordinal()736364>>> dt.weekday()5>>> dt.isocalendar()(2017, 5, 6)>>> dt.isoformat()'2017-02-04T20:57:00.621378'>>> dt.isoformat(sep='/')'2017-02-04/20:57:00.621378'>>> dt.isoformat(sep=' ')'2017-02-04 20:57:00.621378'>>> dt.ctime()'Sat Feb 4 20:57:00 2017'>>> dt.strftime('%Y%m%d %H:%M:%S.%f')'20170204 20:57:00.621378'6. 使用datetime.datetime類對時間戳與時間字符串進行轉換

7. datetime.timedelta類
timedelta對象表示連個不同時間之間的差值。如果使用time模塊對時間進行算術運行,只能將字符串格式的時間 和 struct_time格式的時間對象 先轉換為時間戳格式,然后對該時間戳加上或減去n秒,最后再轉換回struct_time格式或字符串格式,這顯然很不方便。而datetime模塊提供的timedelta類可以讓我們很方面的對datetime.date, datetime.time和datetime.datetime對象做算術運算,且兩個時間之間的差值單位也更加容易控制。
這個差值的單位可以是:天、秒、微秒、毫秒、分鐘、小時、周。
datetime.timedelta類的定義
所有參數都是默認參數,因此都是可選參數。參數的值可以是整數或浮點數,也可以是正數或負數。內部值存儲days、seconds 和 microseconds,其他所有參數都將被轉換成這3個單位:
然后對這3個值進行標準化,使得它們的表示是唯一的:
類屬性
| 類屬性名稱 | 描述 |
|---|---|
| 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) |
| 方法/屬性 | 描述 |
|---|---|
| datetime.datetime.now() | 返回當前本地時間(datetime.datetime對象實例) |
| datetime.datetime.fromtimestamp(timestamp) | 返回指定時間戳對應的時間(datetime.datetime對象實例) |
| datetime.timedelta() | 返回一個時間間隔對象,可以直接與datetime.datetime對象做加減操作 |
實例
>>> import datetime>>>>>> datetime.timedelta(365).total_seconds() # 一年包含的總秒數31536000.0>>> dt = datetime.datetime.now()>>> dt + datetime.timedelta(3) # 3天后datetime.datetime(2017, 2, 8, 9, 39, 40, 102821)>>> dt + datetime.timedelta(-3) # 3天前datetime.datetime(2017, 2, 2, 9, 39, 40, 102821)>>> dt + datetime.timedelta(hours=3) # 3小時后datetime.datetime(2017, 2, 5, 12, 39, 40, 102821)>>> dt + datetime.timedelta(hours=-3) # 3小時前datetime.datetime(2017, 2, 5, 6, 39, 40, 102821)>>> dt + datetime.timedelta(hours=3, seconds=30) # 3小時30秒后 datetime.datetime(2017, 2, 5, 12, 40, 10, 102821)
五、時間格式碼
time模塊的struct_time以及datetime模塊的datetime、date、time類都提供了strftime()方法,該方法可 以輸出一個指定格式的時間字符串。具體格式由一系列的格式碼(格式字符)組成,Python最終調用的是各個平臺C庫的strftme()函數,因此各平臺對全套格式碼的支持會有所不同,具體情況需要參考該平臺上的strftime(3)文檔。下面列出了C標準(1989版)要求的所有格式碼,它們在所有標準C實現的平臺上都可以工作:

六、總結
那么Python中處理時間時,使用time模塊好,還是用datetime模塊好呢?就我個人而言,datetime模塊基本上可以滿足需要,且用起來確實比較方便。對于time模塊,我只是在取當前時間的時間戳時會用到time.time()方法,當然也可以通過datetime.datetime.now().timestamp()來獲取,只是顯得復雜一點。我覺得還是看個人習慣吧,沒有什么絕對的好壞之分。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答
圖片精選