【Python基礎(chǔ)】13個知識點(diǎn),系統(tǒng)整理Python時間處理模塊Datetime
??作者:Lemon
來源:Python數(shù)據(jù)之道
前言
在用 Python 進(jìn)行數(shù)據(jù)處理,尤其是時間序列數(shù)據(jù)的處理,經(jīng)常會涉及處理時間或日期的地方,有些看似簡單的問題,經(jīng)常會混淆,甚至被困住。
本文分享的內(nèi)容來自 Lemon 整理的《Python時間使用指南》,完整版的可以在公眾號 「檸檬數(shù)據(jù)」獲取。
首先要介紹的,是大家平時用的較多的 datetime 模塊,它屬于 Python 的內(nèi)置模塊,功能相對較全。
針對 Datetime 模塊, 《Python時間使用指南》從構(gòu)建時間對象實(shí)例、時間轉(zhuǎn)換、時間對象的運(yùn)算三個方面進(jìn)行了梳理,共涉及 13 個知識點(diǎn),整理的大綱如下:

構(gòu)建時間對象實(shí)例
import?datetime
#?from?datetime?import?date,?datetime,time,timedelta,tzinfo
import?time
時間實(shí)例的構(gòu)造包括 日期(如 2020年10月12日),時間(如 20點(diǎn)10分01秒),或者是包含 date 和 time 的 datetime (如 2020年10月12日20點(diǎn)10分01秒),下面 Lemon 來跟大家介紹下具體的構(gòu)造過程。
日期(date)實(shí)例的構(gòu)造
date 是一個理想化的簡單型日期,屬性有 year , month , day 。
#?構(gòu)造日期?date?實(shí)例
d1?=?datetime.date(2020,10,12)
d1
datetime.date(2020, 10, 12)
#?構(gòu)造日期?date?實(shí)例
d1?=?datetime.date(2020,10,12)
print(d1)
2020-10-12
除了上面的構(gòu)造方式,在 date 實(shí)例化的時候,還可以通過 date.today() 來構(gòu)造當(dāng)天的日期。
datetime.date.today()
datetime.date(2020, 10, 14)
date 類型的日期,可以通過 .year , .month , .day 來獲取日期所屬的 年份,月份,和具體的日期號,這幾個方法在數(shù)據(jù)分析中經(jīng)常會用到。
#?獲取日期所屬的?年份,月份,和具體的日期號
print(f'日期所屬的年份為:{d1.year}')
print(f'日期所屬的月份為:{d1.month}')
print(f'日期具體的日期號為:{d1.day}')
日期所屬的年份為:2020
日期所屬的月份為:10
日期具體的日期號為:12
時間 time 實(shí)例的構(gòu)造
time 是一個獨(dú)立于任何特定日期的理想化時間,其屬性有 hour,minute, second , microsecond 和 tzinfo 。
#?構(gòu)造時間?time?實(shí)例
t1?=?datetime.time(20,10,1)
t1
datetime.time(20, 10, 1)
#?獲取日期所屬的?年份,月份,和具體的日期號
print(f'time 所屬的小時為:{t1.hour}')
print(f'time 所屬的分鐘為:{t1.minute}')
print(f'time 所屬的秒為:{t1.second}')
time 所屬的小時為:20
time 所屬的分鐘為:10
time 所屬的秒為:1
datetime 實(shí)例的構(gòu)造
datetime 是日期和時間的結(jié)合,其屬性有 year,month,day,hour,minute, second , microsecond 和 tzinfo 。
#?構(gòu)造時間?datetime?實(shí)例
dt1?=?datetime.datetime(2020,10,11,20,10,1)
dt1
datetime.datetime(2020, 10, 11, 20, 10, 1)
除了上面的構(gòu)造方式,在 datetime 實(shí)例化的時候,還有其他的一些方式,包括使用 datetime.now() 和 datetime.today(),以及在 date 的基礎(chǔ)上使用 combine 方法等。
dt2?=?datetime.datetime.now()
dt2
datetime.datetime(2020, 10, 14, 15, 12, 20, 303269)
dt3?=?datetime.datetime.today()
dt3
datetime.datetime(2020, 10, 14, 15, 12, 20, 308733)
dt4?=?datetime.datetime.combine(d1,t1)
dt4
datetime.datetime(2020, 10, 12, 20, 10, 1)
通過 datetime 的實(shí)例化,是我們使用時間是經(jīng)常用到的方法,在日常使用過程中,我們可能只需要具體到某天,或者只需要具體到某天的某個時間點(diǎn),這時候,也可以通過 datetime 的一些方法來實(shí)現(xiàn)。
#?從?datetime?來獲取日期
dt4.date()
datetime.date(2020, 10, 12)
#?從?datetime?來獲取具體的時間點(diǎn)
dt4.time()
datetime.time(20, 10, 1)
同樣的 datetime 類型的時間,可以通過 .year , .month , .day 來獲取日期所屬的 年份,月份,和具體的日期號。
#?獲取日期所屬的?年份,月份,和具體的日期號
print(f'日期所屬的年份為:{dt4.year}')
print(f'日期所屬的月份為:{dt4.month}')
print(f'日期具體的日期號為:{dt4.day}')
日期所屬的年份為:2020
日期所屬的月份為:10
日期具體的日期號為:12
還有一個可能涉及到的時間是獲取某天屬于星期幾,可以通過 weekday() 和 isoweekday() 方法來實(shí)現(xiàn)。
#?從?datetime?來獲取日期是星期幾
#?使用?weekday?方法
#?數(shù)字從0開始,0代表星期一,1代表星期二,以此類推
dt4.weekday()
0
#?從?datetime?來獲取日期是星期幾
#?使用?isoweekday?方法
#?數(shù)字從1開始,1代表星期一,2代表星期二,以此類推
dt4.isoweekday()
1
datetime 還有一種方法,在這里也值得介紹下,如果 datetime 的值由于某些原因弄錯了,我們也可以通過 replace() 方法來進(jìn)行更正。這個方法在進(jìn)行數(shù)據(jù)清洗的時候會有用。
replace 方法的參數(shù)如下:
datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
dt5?=?dt4.replace(year=2019)
dt5
datetime.datetime(2019, 10, 12, 20, 10, 1)
timedelta 對象的構(gòu)造
timedelta 對象表示兩個 date 或者 time 或者 datetime 的時間間隔。
class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
所有參數(shù)都是可選的并且默認(rèn)為 0。這些參數(shù)可以是整數(shù)或者浮點(diǎn)數(shù),也可以是正數(shù)或者負(fù)數(shù)。
只有 days, seconds 和 microseconds 會存儲在內(nèi)部。參數(shù)單位的換算規(guī)則如下:
1毫秒會轉(zhuǎn)換成1000微秒。
1分鐘會轉(zhuǎn)換成60秒。
1小時會轉(zhuǎn)換成3600秒。
1星期會轉(zhuǎn)換成7天。
delta?=?datetime.timedelta(weeks=3,
??????????????????days=10,
??????????????????hours=6,
??????????????????minutes=50,
??????????????????seconds=30,
??????????????????microseconds=1000,
??????????????????milliseconds=10000,
?????????????????)
delta
datetime.timedelta(days=31, seconds=24640, microseconds=1000)
tzinfo 介紹
datetime.tzinfo 返回 datetime 對象的時區(qū),前提是在創(chuàng)建 datetime 對象時需傳入 tzinfo 參數(shù),如果沒有傳入則返回值為 None 。
#?如果沒有?pytz?庫,則需要自行安裝
import?pytz
sh?=?pytz.timezone('Asia/Shanghai')
d_tz?=?datetime.datetime(2020,10,12,hour=8,tzinfo=sh)
d_tz.tzinfo
時間轉(zhuǎn)換
時間的三種存在方式:時間對象,時間字符串,時間戳。
時間對象,比如前面介紹的 date 、 datetime 、 time 對象等;時間字符串,如:"2020-10-12";時間戳,如 time.time() 返回的就是時間戳。
在數(shù)據(jù)處理過程中,經(jīng)常會遇到需要將不同形式的時間進(jìn)行轉(zhuǎn)換。這里給大家介紹下常用的方法:
時間對象轉(zhuǎn)字符串
時間對象轉(zhuǎn)換為字符串,可以通過 isoformat 或 strftime 方法來實(shí)現(xiàn)。
strftime 的英文全稱是 str format time ,根據(jù)給定的格式將時間對象轉(zhuǎn)換為字符串
#?將?date?時間對象轉(zhuǎn)換為字符串
d1?=?datetime.date(2020,10,12)
d1.isoformat()
'2020-10-12'
#?用?srtftime?來轉(zhuǎn)換
#?YYYY-MM-DD?形式
d1.strftime('%Y-%m-%d')
'2020-10-12'
#?MM?DD,YYYY?形式
d1.strftime('%b?%d,%Y')
'Oct 12,2020'
#?將?time?時間對象轉(zhuǎn)換為字符串
t1?=?datetime.time(20,10,1)
t1.strftime('%H:%M:%S')
'20:10:01'
#?將?datetime?時間對象轉(zhuǎn)換為字符串
dt2?=?datetime.datetime.now()
dt2.strftime('%Y-%m-%d?%H:%M:%S')
'2020-10-14 15:12:20'
dt2.isoformat()
'2020-10-14T15:12:20.403113'
python 中常見的時間日期格式化符號:
| 指令 | 意義 | 示例 |
|---|---|---|
%a | 當(dāng)?shù)毓ぷ魅盏目s寫。 | Sun, Mon, ..., Sat (en_US);So, Mo, ..., Sa (de_DE) |
%A | 本地化的星期中每日的完整名稱。 | Sunday, Monday, ..., Saturday (en_US);Sonntag, Montag, ..., Samstag (de_DE) |
%w | 以十進(jìn)制數(shù)顯示的工作日,其中0表示星期日,6表示星期六。 | 0, 1, ..., 6 |
%d | 補(bǔ)零后,以十進(jìn)制數(shù)顯示的月份中的一天。 | 01, 02, ..., 31 |
%b | 當(dāng)?shù)卦路莸目s寫。 | Jan, Feb, ..., Dec (en_US);Jan, Feb, ..., Dez (de_DE) |
%B | 本地化的月份全名。 | January, February, ..., December (en_US);Januar, Februar, ..., Dezember (de_DE) |
%m | 補(bǔ)零后,以十進(jìn)制數(shù)顯示的月份。 | 01, 02, ..., 12 |
%y | 補(bǔ)零后,以十進(jìn)制數(shù)表示的,不帶世紀(jì)的年份。 | 00, 01, ..., 99 |
%Y | 十進(jìn)制數(shù)表示的帶世紀(jì)的年份。 | 0001, 0002, ..., 2013, 2014, ..., 9998, 9999 |
%H | 以補(bǔ)零后的十進(jìn)制數(shù)表示的小時(24 小時制)。 | 00, 01, ..., 23 |
%I | 以補(bǔ)零后的十進(jìn)制數(shù)表示的小時(12 小時制)。 | 01, 02, ..., 12 |
%p | 本地化的 AM 或 PM 。 | AM, PM (en_US);am, pm (de_DE) |
%M | 補(bǔ)零后,以十進(jìn)制數(shù)顯示的分鐘。 | 00, 01, ..., 59 |
%S | 補(bǔ)零后,以十進(jìn)制數(shù)顯示的秒。 | 00, 01, ..., 59 |
%f | 以十進(jìn)制數(shù)表示的微秒,在左側(cè)補(bǔ)零。 | 000000, 000001, ..., 999999 |
%z | UTC 偏移量,格式為 ±HHMM[SS[.ffffff]] (如果是簡單型對象則為空字符串)。 | (空), +0000, -0400, +1030, +063415, -030712.345216 |
%Z | 時區(qū)名稱(如果對象為簡單型則為空字符串)。 | (空), UTC, GMT |
%j | 以補(bǔ)零后的十進(jìn)制數(shù)表示的一年中的日序號。 | 001, 002, ..., 366 |
%U | 以補(bǔ)零后的十進(jìn)制數(shù)表示的一年中的周序號(星期日作為每周的第一天)。在新的一年中第一個星期日之前的所有日子都被視為是在第 0 周。 | 00, 01, ..., 53 |
%W | 以十進(jìn)制數(shù)表示的一年中的周序號(星期一作為每周的第一天)。在新的一年中第一個第期一之前的所有日子都被視為是在第 0 周。 | 00, 01, ..., 53 |
%c | 本地化的適當(dāng)日期和時間表示。 | Tue Aug 16 21:30:00 1988 (en_US);Di 16 Aug 21:30:00 1988 (de_DE) |
%x | 本地化的適當(dāng)日期表示。 | 08/16/88 (None);08/16/1988 (en_US);16.08.1988 (de_DE) |
%X | 本地化的適當(dāng)時間表示。 | 21:30:00 (en_US);21:30:00 (de_DE) |
%% | 字面的 '%' 字符。 | % |
字符串轉(zhuǎn)時間對象
字符串轉(zhuǎn)時間對象,用的是 strptime 方法,與 strftime 方法剛好相反。
strptime 的英文全稱是 str parse time ,將字符串解析為給定相應(yīng)格式的時間對象。
s1?=?'2020-10-09'
d?=?datetime.datetime.strptime(s1,'%Y-%m-%d')
d
datetime.datetime(2020, 10, 9, 0, 0)
下面提供了 strftime 方法與 strptime 方法的比較:
strftime | strptime | |
|---|---|---|
| 用法 | 根據(jù)給定的格式將對象轉(zhuǎn)換為字符串 | 將字符串解析為給定相應(yīng)格式的 datetime對象 |
| 方法類型 | 實(shí)例方法 | 類方法 |
| 方法 | date; datetime; time | datetime |
| 簽名 | strftime(format) | strptime(date_string, format) |
需要注意的是,strftime 方法可供 date、time 和 datetime 對象使用,而 strptime 方法僅供 datetime 對象使用。
時間戳轉(zhuǎn)換為時間對象
時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現(xiàn)在的總秒數(shù)。
#?獲取當(dāng)前的時間戳
ts_1?=?time.time()
ts_1
1602660751.071785
#?獲取當(dāng)天00:00:00的時間戳
ts_2?=?int(time.time()/86400)*86400
ts_2
1602633600
#?獲取當(dāng)天23:59:59的時間戳
#?一天有?24*60*60?=??86400?秒
ts_3?=?int(time.time()/86400)*86400+86400-1
ts_3
1602719999
#?將時間戳轉(zhuǎn)換為時間對象
datetime.datetime.fromtimestamp(ts_1)
datetime.datetime(2020, 10, 14, 15, 32, 31, 71785)
#?將時間戳轉(zhuǎn)換為時間對象
datetime.date.fromtimestamp(ts_1)
datetime.date(2020, 10, 14)
將時間對象轉(zhuǎn)換為時間戳
鑒于,時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現(xiàn)在的總秒數(shù)。
因此,將時間對象轉(zhuǎn)換為時間戳?xí)r,直接計(jì)算兩個時間對象的 timedelta ,并將timedelta 以 “秒” 來表示就可以了。
dt1
datetime.datetime(2020, 10, 11, 20, 10, 1)
#?注意這里要用?北京時間
dt_s?=?datetime.datetime(1970,1,1,8)
dt_s
datetime.datetime(1970, 1, 1, 8, 0)
timedelta_1?=?dt1?-dt_s
#?返回時間間隔包含了多少秒
timedelta_s?=?timedelta_1.total_seconds()
timedelta_s
1602418201.0
這里我們來反推下,看我們將時間對象轉(zhuǎn)換為時間戳,是否正確。
#?將時間戳轉(zhuǎn)換為時間對象
datetime.datetime.fromtimestamp(timedelta_s)
datetime.datetime(2020, 10, 11, 20, 10, 1)
時間對象的運(yùn)算
獲取當(dāng)天最小時間和最大時間
#?獲取當(dāng)天最小時間
datetime.datetime.combine(datetime.date.today(),datetime.time.min)
datetime.datetime(2020, 10, 14, 0, 0)
#?獲取當(dāng)天最大時間
datetime.datetime.combine(datetime.date.today(),datetime.time.max)
datetime.datetime(2020, 10, 14, 23, 59, 59, 999999)
獲取當(dāng)前日期的前幾天/后幾天
#?獲取明天
datetime.date.today()?+?datetime.timedelta(days=1)
datetime.date(2020, 10, 15)
#?獲取明天
datetime.date.today()?-?datetime.timedelta(days=1)
datetime.date(2020, 10, 13)
獲取本周或本月第一天及最后一天
d_today?=?datetime.date.today()
d_today
datetime.date(2020, 10, 14)
#?獲取本周第一天
d_today?-?datetime.timedelta(d_today.weekday())
datetime.date(2020, 10, 12)
#?獲取本周最后一天
d_today?+?datetime.timedelta(6-d_today.weekday())
datetime.date(2020, 10, 18)
計(jì)算兩個日期相差多少天
#?timedelta?對象的計(jì)算
td1?=?dt2?-?dt1
td1
datetime.timedelta(days=2, seconds=68539, microseconds=403113)
td1.days
2
注意下,如果需要計(jì)算兩個日期之間總共相差多少秒,應(yīng)該用 total_seconds() 方法。
td1.seconds
68539
td1.total_seconds()
241339.403113
參考文檔:
https://docs.python.org/zh-cn/3/library/datetime.html#strftime-strptime-behavior https://segmentfault.com/a/1190000012112097 https://blog.csdn.net/qq_34493908/article/details/80888052 https://zhuanlan.zhihu.com/p/96384066
往期精彩回顧
獲取本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:
https://t.zsxq.com/qFiUFMV
本站qq群704220115。
加入微信群請掃碼:
