天天看點

小白學python:時間和日期 (time, datetime) (二)引言一、時間資訊提取二、時間計算三、時間生成

目錄

  • 引言
  • 一、時間資訊提取
    • 如何擷取某一日期是星期幾、一年中的第幾天、一年中的第幾周?
    • 如何提取部分時間資訊?
  • 二、時間計算
    • 計算兩個日期間隔的天數
    • 計算某日期前(後)N天的日期
    • 計算某日期前(後)N月(年)的日期 — dateutil.relativedelta.relativedelta()
    • 計算某個月有多少天
  • 三、時間生成
    • pd.date_range()

引言

“時間”是我們在進行資料分析時十分重要的次元,比如日期、分時,是以在初學python時,學會與“時間”相處是我們的必修課,這就要學習python中兩個非常重要的處理時間的庫——

time

datetime

import time,datetime
           

《小白學python:時間和日期 (time, datetime) (一)》向讀者介紹了python中常見的時間格式和不同時間格式的互相轉換,本文将在此基礎上介紹:

  • 時間資訊提取

    比如:某一日期是星期幾、一年中的第幾天、一年中的第幾周 ;提取時間中的年、月、日 ···

  • 時間計算

    比如:兩個日期間隔的天數、擷取日期前(後)N天的日期 ···

  • 時間生成

    比如:生成兩個日期之間的所有日期、生成各月末的日期 ···

Let’s get started!

一、時間資訊提取

如何擷取某一日期是星期幾、一年中的第幾天、一年中的第幾周?

這個問題相信看過《小白學python:時間和日期 (time, datetime) (一)》的讀者已經有了答案——可以直接用time.struct_time時間格式來看。

下面舉個例子:

t_str='2020 7 25'

time.strptime(t_str,'%Y %m %d')
>>>
time.struct_time(tm_year=2020, tm_mon=7, tm_mday=25, 
tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=207,
tm_isdst=-1)
           

2020年7月25日的

tm_wday=5

,是以該日為周六(再次強調!!! time.struct_time中的tm_wday為0-6 對應周一~周日),

tm_yday=207

,是以該日是2020年的第207天,而要擷取該日是這年中的第幾周,直接取207除以7的商再加1即可。

如何提取部分時間資訊?

比如輸入的時間字元串是‘2020-07-25 12:30:00’,我想隻保留日期部分,同時再加上這一天是周幾,即“2020-07-25 Sat”。

t_datetime=datetime.datetime(2020,7,25,12,30,0)

datetime.datetime.strftime(t_datetime,'%Y-%m-%d %a')
>>>'2020-07-25 Sat'
#或者
t_datetime.strftime('%Y-%m-%d %a')
>>>'2020-07-25 Sat'
           

當從其他時間格式轉為字元串形式時,我們可以有選擇地提取時間資訊,比如在上述例子中,我們輸入的時間包括年月日時分秒(2020,7,25,12,30,0),而輸出的時間則是基于自己設定的

format:'%Y-%m-%d %a'

二、時間計算

我們經常會對日期進行一些計算,比如兩個日期間隔的天數、某日期前(後)N天的日期是多少、某個月有多少天 ···

計算兩個日期間隔的天數

先将時間轉化datetime.datetime格式,然後直接相減。

t_str1='2020 7 20'
t_str2='2020 7 25'

t_datetime1=datetime.datetime.strptime(t_str1,'%Y %m %d')
t_datetime2=datetime.datetime.strptime(t_str2,'%Y %m %d')

t_datetime2-t_datetime1
>>>datetime.timedelta(days=5)

#(t_datetime2-t_datetime1).days
5
           

計算某日期前(後)N天的日期

datetime.timedelta()

Difference between two datetime values.

timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

t_datetime=datetime.datetime(2020,7,25,12,30,0)

t_datetime+datetime.timedelta(5) #預設為days=5 5日後
>>>datetime.datetime(2020, 7, 30, 12, 30)

t_datetime-datetime.timedelta(weeks=1) #1周前
>>>datetime.datetime(2020, 7, 18, 12, 30)

t_datetime+datetime.timedelta(hours=2,minutes=20) #2小時20分鐘後
>>>datetime.datetime(2020, 7, 25, 14, 50)
           

計算某日期前(後)N月(年)的日期 — dateutil.relativedelta.relativedelta()

在上述計算某日期前(後)N天的日期時,我們使用了

datetime.timedelta()

,但是可以看到,該函數的參數中并沒有

months

years

,是以當我們需要計算某一日期前(後)N月或年時就會略顯麻煩,由于會涉及到月份、年份的天數問題。為此,下面介紹更為強大的

dateutil.relativedelta.relativedelta()

,該函數是基于datetime庫編寫的。

首先,看一下該函數的參數:

relativedelta(dt1=None, dt2=None, years=0,months=0, days=0,leapdays=0, weeks=0, hours=0,minutes=0, seconds=0,microseconds=0,year=None,month=None, day=None,weekday=None,yearday=None,nlyearday=None, hour=None,minute=None,second=None,microsecond=None,)

參數包括複數形式的

years

months

days

weeks

hours

minutes

seconds

microseconds

,以及它們對應的單數形式

year

month

day

hour

minute

second

microsecond

簡單解釋一下:單數形式的參數值将會替換datetime的相應成分值,而複數形式的參數值代表時間間隔。

如果該函數的單數和複數形式的參數同時出現,則先執行單數形式的參數,再執行複數形式的參數,即首先替換datetime的相應成分值,然後加減時間間隔,進而得到最終的時間。

下面進行代碼示範:

from dateutil.relativedelta import relativedelta

dt = datetime.datetime(2020, 7, 25, 12, 30, 0)

delta=relativedelta(month=8,day=26) #替換月和日
dt+delta
>>>datetime.datetime(2020, 8, 26, 12, 30)

delta=relativedelta(months=1) #1月後
dt+delta
>>>datetime.datetime(2020, 8, 25, 12, 30)

delta=relativedelta(months=-6) #6月前
dt+delta
>>>datetime.datetime(2020, 1, 25, 12, 30)

delta=relativedelta(month=8,day=26,years=1,months=2) 
# 先将時間變成(2020,8,26,12,30),然後年份+1,月份+2,
# 時間變成(2021,10,26,12,30)
dt+delta
>>>datetime.datetime(2021, 10, 26, 12, 30)
           

計算某個月有多少天

我們使用已經學過的函數來計算任意一個月有多少天,代碼如下:

t_str='2020 2'
t_datetime=datetime.datetime.strptime(t_str,'%Y %m')
t_datetime_1M=t_datetime+relativedelta(months=1)
t_datetime_1M-t_datetime
>>> datetime.timedelta(days=29)

           

或者,我們也可以使用

calendar.monthrange()

該函數輸入年和月,輸出包含兩個值的tuple,第一個值是該月第一天是周幾(0=周一),第二個值是該月的天數。

calendar.monthrange(2020,2)
>>>(5,29)
           

至此,我們通過幾個例子對python中的時間處理有了更好的了解和運用。當然,我們可以使用這些函數去處理其他時間運算。

三、時間生成

接下來,我們學習如何生成一段時間。比如:生成兩個日期之間的所有日期、生成各月末的日期 、生成等間隔的一段時間等等。

pd.date_range()

介紹該函數幾個重要參數:

start

開始時間,格式可以是str或datetime。

end

結束時間,格式可以是str或datetime。

periods

間隔數或要生成的時間數目。

freq

時間間隔,一般用頻率字元串,如’D’表示1天,‘H’表示1小時。

該函數傳回DatetimeIndex

代碼示範:

pd.date_range(start='2020-07-25', end='2020-07-27')
#預設頻率為'D',即日
>>>DatetimeIndex(['2020-07-25', '2020-07-26', 
>'2020-07-27'], dtype='datetime64[ns]', freq='D')

pd.date_range(start='2020-07-25', periods=3)
#從start開始往後3天
>>>DatetimeIndex(['2020-07-25', '2020-07-26', 
'2020-07-27'], dtype='datetime64[ns]', freq='D')

pd.date_range(end='2020-07-25', periods=3)
#從end開始往前3天
>>>DatetimeIndex(['2020-07-23', '2020-07-24', 
'2020-07-25'], dtype='datetime64[ns]', freq='D')

pd.date_range(start='2020-07-25', end='2020-07-27',periods=4)
#開始日期和結束日期之間等間隔取4個時間
>>>DatetimeIndex(['2020-07-25 00:00:00', '2020-07-25 16:00:00',
'2020-07-26 08:00:00', '2020-07-27 00:00:00'],
dtype='datetime64[ns]', freq=None)

pd.date_range(start='2020-07-25', end='2020-12-27',freq='M')
#'M'對應月底(calendar month end)
>>>DatetimeIndex(['2020-07-31', '2020-08-31', '2020-09-30', '2020-10-31',
'2020-11-30'],dtype='datetime64[ns]', freq='M')

pd.date_range(start='2020-07-25', end='2020-07-26',freq='5H')
#'5H'對應5小時
>>>DatetimeIndex(['2020-07-25 00:00:00', '2020-07-25 05:00:00',
'2020-07-25 10:00:00', '2020-07-25 15:00:00','2020-07-25 20:00:00'],
dtype='datetime64[ns]', freq='5H')
           

更多關于freq參數的頻率字元串(frequency strings)前往這兒。

The End~~