### 引入
DataFrame處理的數(shù)據(jù)中經(jīng)常會(huì)看到某一列的數(shù)據(jù)類型是時(shí)間類型或者是字符串但是需要轉(zhuǎn)成時(shí)間類型。什么是時(shí)間類型?與Python中使用的模塊time、datetime等有什么聯(lián)系?
首先看看下面這張圖,如果看到數(shù)據(jù)的如果類型是**datetime64[ns]**說明就是DataFrame中的日期時(shí)間類型。
但是有時(shí)候我們看到的數(shù)據(jù)明明都是日期格式,怎么就偏偏不是**datetime64[ns]**類型呢?而顯示的是object類型,比如下面你看到的數(shù)據(jù)
上面看到都是object類型,object類型在獲取日期時(shí)間的年月日時(shí)分秒的時(shí)候就不方便,比獲取
### 簡單回顧Python日期時(shí)間模塊
python標(biāo)準(zhǔn)庫包含用于日期(date)和時(shí)間(time)數(shù)據(jù)的數(shù)據(jù)類型,而且還有日歷方面的功能。我們主要會(huì)用到datetime、time以及calendar模塊。
#### datetime模塊
datetime模塊常用的類如下:
| 類型 | 說明 |
| --------- | ------------------------------------------ |
| date | 日期對(duì)象,以公歷形式存儲(chǔ)日期(年、月、日) |
| time | 時(shí)間對(duì)象,將時(shí)間存儲(chǔ)為:時(shí)、分、秒、毫秒 |
| datetime | 存儲(chǔ)日期和時(shí)間 |
| timedelta | 時(shí)間間隔,表示兩個(gè)datetime之間的差 |
附錄(日期和時(shí)間的格式化符號(hào)表)
| 符號(hào) | 說明 |
| :--- | :---------------------------------------- |
| `%y` | 兩位數(shù)的年份表示(00-99) |
| `%Y` | 四位數(shù)的年份表示(000-9999) |
| `%m` | 月份(01-12) |
| `%d` | 月內(nèi)中的一天(0-31) |
| `%H` | 24小時(shí)制小時(shí)數(shù)(0-23) |
| `%I` | 12小時(shí)制小時(shí)數(shù)(01-12) |
| `%M` | 分鐘數(shù)(00=59) |
| `%S` | 秒(00-59) |
| `%a` | 本地簡化星期名稱 |
| `%A` | 本地完整星期名稱 |
| `%b` | 本地簡化的月份名稱 |
| `%B` | 本地完整的月份名稱 |
| `%c` | 本地相應(yīng)的日期表示和時(shí)間表示 |
| `%j` | 年內(nèi)的一天(001-366) |
| `%p` | 本地A.M.或P.M.的等價(jià)符 |
| `%U` | 一年中的星期數(shù)(00-53)星期天為星期的開始 |
| `%w` | 星期(0-6),星期天為星期的開始 |
| `%W` | 一年中的星期數(shù)(00-53)星期一為星期的開始 |
| `%x` | 本地相應(yīng)的日期表示 |
| `%X` | 本地相應(yīng)的時(shí)間表示 |
| `%Z` | 當(dāng)前時(shí)區(qū)的名稱 |
| `%%` | %號(hào)本身 |
date類代碼演示:
> datetime.date(year, month, day)
```python
from datetime import date
# 獲取當(dāng)前的日期
today = date.today()
print(today) # 2021-08-10
print(today.day) # 10
# 也可以創(chuàng)建一個(gè)指定的日期對(duì)象
tomorrow = date(2021,8,11)
print(tomorrow) # 2021-08-11
print(tomorrow.day) # 11
print(today.strftime('%Y年%m月%d日')) # 相當(dāng)于格式化輸出
```
time類代碼演示:
> datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] )
```python
from datetime import time
# 創(chuàng)建一個(gè)time對(duì)象
t = time(14,20,59,83999)
print(t) # 14:20:59.083999
print(t.strftime('%H:%M:%S')) # 相當(dāng)于格式化輸出
```
datetime代碼演示:
> datetime相當(dāng)于date和time結(jié)合起來
> datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] )
```python
from datetime import datetime
now = datetime.now()
print(now) # datetime.datetime(2021, 8, 10, 15, 21, 6, 581886)
print(now.year) # 2021
print(now.month) # 8
print(now.day) # 21
print(now.date())
print(now.time())
print(now.strftime('%Y年%m月%d日 %H:%M:%S')) # 格式化輸出
```
timedelta代碼演示:
> 使用timedelta可以很方便的在日期上做天days,小時(shí)hours,分鐘,秒,毫秒,微妙的時(shí)間計(jì)算,如果要計(jì)算月份則需要另外的辦法。
```python
from datetime import *
dt = datetime.now()
#日期減一天,dt1和dt2都表示昨天,兩種不同的操作方式
dt1 = dt + timedelta(days=-1) # 昨天
dt2 = dt - timedelta(days=1) # 昨天
dt3 = dt + timedelta(days=1) # 明天
print(dt1)
print(dt2)
print(dt3)
# 也可以小時(shí)的加減
t1 = dt + timedelta(hours=1)
print(t1)
```
**案例**:獲取指定日期月份的**最后一天的日期和本月天數(shù)**
```
from datetime import datetime,date,timedelta
date1 = datetime.now()
def eomonth(date_object):
if date_object.month == 12:
next_month_first_date = date(date_object.year+1,1,1)
else:
next_month_first_date = date(date_object.year, date_object.month+1, 1)
return next_month_first_date - timedelta(1)
print(eomonth(date1))
print(eomonth(date1).day)
```
#### time模塊
time模塊中時(shí)間表現(xiàn)的格式主要有三種:
> a、timestamp時(shí)間戳,時(shí)間戳表示的是從1970年1月1日00:00:00開始按秒計(jì)算的偏移量
>
> b、struct_time時(shí)間元組,共有九個(gè)元素組。
>
> c、format time 格式化時(shí)間,已格式化的結(jié)構(gòu)使時(shí)間更具可讀性。包括自定義格式和固定格式
```python
import time
# 生成timestamp
print(time.time()) # 時(shí)間戳?xí)r間
print(time.localtime()) # 生成struct_time
print(time.strptime('2021-08-10 16:37:06', '%Y-%m-%d %X')) # 格式化時(shí)間轉(zhuǎn)struct_time
print(time.strftime("%Y-%m-%d %X",time.localtime())) # struct_time轉(zhuǎn)格式化時(shí)間
```
當(dāng)然還有大家常用的time.sleep(seconds)休眠。
### panads日期時(shí)間操作
我們?cè)跀?shù)據(jù)分析的時(shí)候時(shí)間日期的操作無非下面幾種:
#### object轉(zhuǎn)日期時(shí)間類型
| 原有數(shù)據(jù)類型(object)和展示形式 | 想得到的格式 | 代碼 |
| -------------------------------- | ------------------- | ----------------------------------------------------- |
| 2021-08-10 | 2021-08-10 | pd.to_datetime(data['time_object']) |
| 08/10/21 | 2021-08-10 | pd.to_datetime(data['time_object'],format='%m/%d/%y') |
| 2021-08-10 14:20:59 | 2021-08-10 14:20:59 | pd.to_datetime(data['time_object']) |
| 2021年08月 | 2021-08-01 | pd.to_datetime(data['time_object'],format='%Y年%m月') |
#### 日期轉(zhuǎn)固定格式的
| 原有數(shù)據(jù)類型(datetime64)和展示形式 | 想得到的格式 | 代碼 |
| ------------------------------------ | ------------------- | ------------------------------------------------------------ |
| 2021-08-10 14:20:59 | 2021-08-10 | data['datetime_col'].dt.date 或者pd.to_datetime(data['datetime_col'].dt.strftime('%Y-%m-%d')) |
| 2021-08-10 14:20:59 | 2021-08-10 00:00:00 | data['datetime_col'].dt.strftime('%Y-%m-%d 00:00:00') |
#### 提取日期類型的年月日
| 原有數(shù)據(jù)類型(datetime64)和展示形式 | 想得到的格式 | 代碼 |
| ------------------------------------ | ------------ | ------------------------------ |
| 2021-08-10 14:20:59 | 2021 | data['datetime_col'].dt.year |
| 2021-08-10 14:20:59 | 8 | data['datetime_col'].dt.month |
| 2021-08-10 14:20:59 | 10 | data['datetime_col'].dt.day |
| 2021-08-10 14:20:59 | 14 | data['datetime_col'].dt.hour |
| 2021-08-10 14:20:59 | 20 | data['datetime_col'].dt.minute |
| 2021-08-10 14:20:59 | 59 | data['datetime_col'].dt.second |
#### 時(shí)間差的計(jì)算
| startdate | enddate | difference | 代碼 |
| ------------------- | ------------------- | ---------- | ------------------------------------------------------------ |
| 2018-02-14 12:20:36 | 2019-02-28 13:38:41 | 379.054225 | (data['datetime_col']-data['datetime_col'])/np.timedelta64(1,'D') |
np.timedelta64具體內(nèi)容可以參看文檔:https://numpy.org/doc/stable/reference/arrays.datetime.html文檔中給出的案例非常詳細(xì)。