如何使用 Python datetime 模組對日期時間進行運算?timedelta 類別介紹

閱讀 19:31·字數 5856·發佈 
Youtube 頻道
訂閱 133

Python datetime 模組的 date,time,datetime 物件之間的運算

對於 Pythondatetime模組的datetime以及datetime物件,可使用減法運算子和比較運算子進行運算,參與運算的物件需要是相同的型別,比如date物件不能與timedatetime物件進行運算。

使用減法運算子-可以計算兩個日期(date物件)或日期時間(datetime物件)之間的差值,這將傳回 Pythondatetime模組的timedelta物件。

date1 - date2
datetime1 - datetime2

無法計算 Python datetime 模組的 time 物件之間的時間差值

你可以使用減法運算子-計算日期或日期時間之間的差值,但對於 Pythondatetime模組的time物件,無法通過減法運算子-計算他們之間的差值,這將導致例外狀況TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

from datetime import date, datetime
# 計算兩個日期之間差值
date(2024, 10, 10) - date(2024, 10, 1)
datetime.timedelta(days=9)
# 計算兩個日期時間之間差值
datetime(2024, 10, 1, 0, 0, 0, 1234) - datetime(2024, 10, 10, 0, 0, 1, 123)
datetime.timedelta(days=-10, seconds=86399, microseconds=1111)

使用比較運算子==!=可以計算兩個日期(date物件),兩個時間(time物件)或日期時間(datetime物件)是否相等或是否不相等。

date1 == date2
date1 != date2
time1 == time2
time1 != time2
datetime1 == datetime2
datetime1 != datetime2

表示相同日期的 Python datetime 模組的 date 與 datetime 物件不相等

即便表示了相同的日期,Pythondatetime模組的datedatetime物件不會相等,比如,date(2024,1,1)datetime(2024,1,1)不相等。

from datetime import date, time, datetime
# 兩個日期相等
date(2024, 10, 3) == date(2024, 10, 3)
True
# 兩個時間相等
time(1, 1) == time(1, 1, 0, 0)
True
# 兩個日期時間相等
datetime(2024, 10, 3, 1) != datetime(2024, 10, 3, 1, 0)
False
# date 和 datetime 不相等
date(2024, 10, 3) == datetime(2024, 10, 3)
False

使用比較運算子<<=可以計算一個日期(date物件)是否小於或小於等於另一個日期,計算一個時間(time物件)是否小於或小於等於另一個時間,計算一個日期時間(datetime物件)是否小於或小於等於另一個日期時間。

使用比較運算子>>=可以計算一個日期(date物件)是否大於或大於等於另一個日期,計算一個時間(time物件)是否大於或大於等於另一個時間,計算一個日期時間(datetime物件)是否大於或大於等於另一個日期時間。

date1 < date2
date1 <= date2
time1 < time2
time1 <= time2
datetime1 < datetime2
datetime1 <= datetime2
date1 > date2
date1 >= date2
time1 > time2
time1 >= time2
datetime1 > datetime2
datetime1 >= datetime2

from datetime import date, time, datetime
# 日期 2024-10-3 更大
date(2024, 10, 3) < date(2024, 10, 1)
False
# 時間 23:59:59 更大
time(23, 59, 59) > time(23, 59)
True
# 日期時間 2024-10-3 23:59:59.123456 更大
datetime(2024, 10, 3, 23, 59, 59) <= datetime(2024, 10, 3, 23, 59, 59, 123456)
True

時區

如果你想了解時區資訊對timedatetime物件運算的影響,那麽可以檢視Python datetime 模組的時區物件 tzinfo 對日期時間運算的影響一段。

Python datetime 模組的 timedelta 類別

Pythondatetime模組的timedelta類別,用於表示兩個日期或兩個日期時間之間的差值,該類別的執行個體通常由包含減法運算子-的運算式計算得到,也可以使用建構子建立,傳遞給建構子的參數將被換算累計為timedelta物件的dayssecondsmicroseconds的屬性,這意味著轉遞的任意參數都將成為日期時間差值的一部分。

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

days 參數

days參數表示日期時間差值持續的天數。

seconds 參數

seconds參數表示日期時間差值持續的秒數。

microseconds 參數

microseconds參數表示日期時間差值持續的微秒。

milliseconds 參數

milliseconds參數表示毫秒數(1秒等於1000毫秒),他將被累計為微秒(1毫秒等於1000微秒)。

minutes 參數

minutes參數表示分鐘數,他將被累計為秒(1分鐘等於60秒)。

hours 參數

hours參數表示小時數,他將被累計為秒(1小時等於3600秒)。

weeks 參數

weeks參數表示星期數,他將被累計為天(1星期等於7天),秒(如果有秒的部分)和微秒(如果有微秒的部分)。

Python datetime 模組的 timedelta 類別的建構子參數可以是負數和小數

在 Pythondatetime模組的timedelta類別的建構子中,建構子的參數可以是負數和小數,除了表示微秒的microseconds,該參數可以是負數但不能是小數。此外,在參數milliseconds所表示的毫秒被轉換為微秒時,僅前三位小數有效(其余部分會被拾入),比如,毫秒11.2345會被轉換為微秒11235,毫秒11.2344會被轉換為微秒11234

對於建構子參數daysweekshoursminutesseconds,如果擁有小數部分,則相當於將其計算為對應秒數,其微秒部分為六位(其余部分會被拾入)。比如,運算式timedelta(days=0.5555555555),其微秒部分的計算結果為9999952,拾入後為999995datetime.timedelta(seconds=47999,microseconds=999995)),運算式timedelta(days=0.55555555555),其微秒部分的計算結果為99999952,拾入後為1秒(datetime.timedelta(seconds=48000))。

from datetime import timedelta
# 建立 timedelta 物件
timedelta(days=1, hours=-24, minutes=60.5)
datetime.timedelta(seconds=3630)
timedelta(minutes=1, milliseconds=123, microseconds=111567)
datetime.timedelta(seconds=60, microseconds=234567)
timedelta(days=0.5, weeks=0.5, hours=0.5, minutes=0.5)
datetime.timedelta(days=4, seconds=1830)
timedelta(seconds=0.5, milliseconds=0.5)
datetime.timedelta(microseconds=500500)

取得 Python datetime 模組的 timedelta 物件所對應的日期時間差值資訊

Pythondatetime模組的timedelta物件擁有以下唯讀屬性,可用於取得日期時間差值的相關資訊,其中days屬性表示日期時間差值所持續的天數(大於等於-999999999,小於等於999999999),seconds屬性表示日期時間差值所持續的秒數(大於等於0,小於86400),microseconds屬性表示日期時間差值所持續的微秒(大於等於0,小於1000000)。

timedelta.days
timedelta.seconds
timedelta.microseconds

Pythondatetime模組的timedelta物件的total_seconds方法,可用於取得日期時間差值對應的總秒數(不同於seconds屬性),微秒部分將被表示為小數,因此,該方法的傳回值是一個浮點數。

timedelta.total_seconds()

Python datetime 模組的 timedelta 物件的 seconds 屬性和 total_seconds 方法的區別

Pythondatetime模組的timedelta物件的total_seconds方法所傳回的秒數可以表示完整的日期時間差值,而seconds屬性需要和daysmicroseconds屬性一起才能表示完整的日期時間差值。

from datetime import timedelta
# 取得日期時間差值資訊
td = timedelta(days=1, weeks=1, hours=0.5, milliseconds=1.234)
td.days
8
td.seconds
1800
td.microseconds
1234
# 總秒數
td.total_seconds()
693000.001234

Python datetime 模組的 timedelta 物件的 total_seconds 方法可能失真

這裏需要指出,對於 Pythondatetime模組的timedelta物件的total_seconds方法,如果日期時間的差值過大,那麽其傳回值的小數(微秒)部分可能會失真。

from datetime import timedelta
# 差值過大,微秒部分失真
timedelta(days=365 * 3000, microseconds=123456).total_seconds()
94608000000.12346

Python datetime 模組的 timedelta 物件所允許的最小和最大日期時間差值

Pythondatetime模組的timedelta類別的類別變數minmax,分別表示所允許的最小日期時間差值和最大日期時間差值,其中min等價於運算式timedelta(days=-999999999)運算得到的timedelta物件,max等價於運算式timedelta(days=999999999,hours=23,minutes=59,seconds=59,microseconds=999999)timedelta(days=999999999,seconds=86399,microseconds=999999)運算得到的timedelta物件。

timedelta.min
timedelta.max

from datetime import timedelta
# 最小日期時間差值
timedelta.min
datetime.timedelta(days=-999999999)
# 最大日期時間差值
timedelta.max
datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)

Python datetime 模組的 timedelta 物件之間的運算

你可以使用某些運算子對 Pythondatetime模組的timedelta物件進行運算,如果運算的結果是一個新的timedelta物件,並且日期時間差值超出了timedelta物件的表達範圍(比如-timedelta.max),那麽可能會引發例外狀況OverflowError,如果涉及除法運算(比如,取余或整除)的除數為0或等價於timedelta()timedelta物件,那麽可能會引發例外狀況ZeroDivisionError

使用加法運算子+和減法運算子-,可以在 Pythondatetime模組的timedelta物件之間進行加法或減法運算,這相當於將日期時間的差值相加或相減,其運算結果是一個新的timedelta物件。

timedelta1 + timedelta2
timedelta1 - timedelta2

from datetime import timedelta
# 將兩個日期時間差值相加
timedelta(days=1, hours=324) + timedelta(weeks=3)
datetime.timedelta(days=35, seconds=43200)
# 將兩個日期時間差值相減
timedelta(hours=3, minutes=20) - timedelta(minutes=45)
datetime.timedelta(seconds=9300)

使用除法運算子/,可以在 Pythondatetime模組的timedelta物件之間進行除法運算,這相當於將日期時間的差值相除,其運算結果是一個表示倍數關系的浮點數。

使用整除運算子//,可以在 Pythondatetime模組的timedelta物件之間進行整除運算,這相當於將日期時間的差值整除(運算結果為整數,丟棄結果中的小數部分)。

timedelta1 / timedelta2
timedelta1 // timedelta2

from datetime import timedelta
# 將兩個日期時間差值相除
timedelta(5) / timedelta(2)
2.5
timedelta(1) / timedelta(hours=48)
0.5
# 將兩個日期時間差值整除
timedelta(5) // timedelta(2)
2
timedelta(1) // timedelta(hours=48)
0

使用取余運算子%,可以在 Pythondatetime模組的timedelta物件之間進行取余運算,這相當於將日期時間的差值相除然後取得余數,其運算結果是一個新的timedelta物件(兩個timedelta物件的dayssecondsmicroseconds屬性相除,並通過余數來建立新的timedelta物件)。

timedelta1 % timedelta2

from datetime import timedelta
# 對兩個日期時間差值取余
timedelta(days=5, hours=5, microseconds=5) % timedelta(days=2, minutes=120, milliseconds=0.002)
datetime.timedelta(days=1, seconds=3600, microseconds=1)

通過 Python 的divmod函式,可同時完成對兩個datetime模組的timedelta物件的整除和取余運算,運算的結果是一個 Python 元組,元組的第一個元素是整除的結果(與整除運算子//的結果相同),第二個元素是取余的結果(與取余運算子%的結果相同)。

divmod(timedelta1, timedelta2)

from datetime import timedelta
# 同時整除和取余
divmod(timedelta(5), timedelta(2))
(2, datetime.timedelta(days=1))

使用一元運算子+,可以獲得一個新的 Pythondatetime模組的timedelta物件,新物件所表示的日期時間差值與原有timedelta物件相同。使用一元運算子-,可以獲得一個新的 Pythondatetime模組的timedelta物件,新物件將根據原有timedelta物件的daysseconds以及microseconds屬性的相反數建立。

+timedelta
-timedelta

from datetime import timedelta
# 一元運算子
+timedelta(hours=23, minutes=59, seconds=59)
datetime.timedelta(seconds=86399)
-timedelta(hours=23, minutes=59, seconds=59)
datetime.timedelta(days=-1, seconds=1)

使用比較運算子==!=可以計算兩個日期時間差值(timedelta物件)是否相等或是否不相等。

timedelta1 == timedelta2
timedelta1 != timedelta2

from datetime import date, timedelta
# 1 分鐘等於 60 秒
timedelta(minutes=1) == timedelta(seconds=60)
True
# 兩邊運算式相等
timedelta(days=1) != date(2024, 10, 1) - date(2024, 9, 30)
False

使用比較運算子<<=可以計算一個日期時間差值(timedelta物件)是否小於或小於等於另一個日期時間差值。使用比較運算子>>=可以計算一個日期時間差值(timedelta物件)是否大於或大於等於另一個日期時間差值。

timedelta1 < timedelta2
timedelta1 <= timedelta2
timedelta1 > timedelta2
timedelta1 >= timedelta2

from datetime import timedelta
# 比較日期時間差值大小
timedelta(hours=1.5) > timedelta(minutes=80)
True
timedelta(milliseconds=1.234) > timedelta(microseconds=1235)
True

Python datetime 模組的 timedelta 物件與數值型別的運算

除了在 Pythondatetime模組的timedelta物件之間進行運算,以下運算子還可以完成timedelta物件與數值型別之間的運算,如果運算的結果是一個新的timedelta物件,並且日期時間差值超出了timedelta物件的表達範圍,那麽可能會引發例外狀況OverflowError

使用乘法運算子*和除法運算子/,可以完成timedelta物件與 Python 整數或浮點數之間的乘法和除法運算,這相當日期時間差值被擴大或縮小指定的倍數,其運算結果是一個新的timedelta物件。

使用整除運算子//,可以完成timedelta物件與 Python 整數之間的整除運算,該運算子與除法運算子/類似,但會丟棄微秒的小數部分而不是進行拾入。

timedelta * int|float
int|float * timedelta
timedelta / int|float
timedelta1 // int

from datetime import timedelta
# 浮點數與日期時間差值相乘
3.5 * timedelta(days=1, hours=30)
datetime.timedelta(days=7, seconds=75600)
# 日期時間差值與整數相除
timedelta(days=1) / 35
# 微秒的小數部分會被拾入
datetime.timedelta(seconds=2468, microseconds=571429)
timedelta(days=1) // 35
# 丟棄微秒的小數部分
datetime.timedelta(seconds=2468, microseconds=571428)

Python datetime 模組的 timedelta 物件與 date,datetime 物件之間的運算

使用加法運算子+和減法運算子-,Pythondatetime模組的timedelta物件可以同datedatetime物件進行加法或減法運算,其運算結果是一個新的datedatetime物件,這相當於將日期時間增加或減去一個差值。

需要指出的是,對於 Pythondatetime模組的date物件,僅timedelta物件的days屬性會參與運算。

date|datetime + timedelta
date|datetime - timedelta
timedelta + date|datetime
timedelta - date|datetime

from datetime import date, datetime, timedelta
# 增加 6 天
timedelta(weeks=0.9) + date(2024, 1, 1)
datetime.date(2024, 1, 7)
# 減去 1 天 11 小時
datetime(2024, 1, 1, 10, 10) - timedelta(days=1, hours=11)
datetime.datetime(2023, 12, 30, 23, 10)

時區

如果你想了解時區資訊對timedeltadatetime物件運算的影響,那麽可以檢視Python datetime 模組的時區物件 tzinfo 對日期時間運算的影響一段。

取得 Python datetime 模組的 timedelta 物件所表示的日期時間差值的絕對值

通過 Python 的abs函式,可以取得 Pythondatetime模組的timedelta物件所表示的日期時間差值的絕對值,當timedelta物件的days屬性大於等於0時,abs函式的傳回值等價於使用一元運算子+,當timedelta物件的days屬性小於0時,abs函式的傳回值等價於使用一元運算子-

abs(timedelta)

from datetime import timedelta
# 雖然參數 days 為 1,但最終的 days 屬性為 -1
td = timedelta(days=1, hours=-25)
td
datetime.timedelta(days=-1, seconds=82800)
abs(td)
# 等同於 timedelta(days=1, seconds=-82800)
datetime.timedelta(seconds=3600)

將 Python datetime 模組的 timedelta 物件所表示的日期時間差值轉換為字串

通過 Python 的repr函式或字串型別的建構子str,可以將 Pythondatetime模組的timedelta物件所表示的日期時間差值轉換為一個字串。當然,呼叫timedelta物件的__repr____str__方法可實作相同效果。

repr(timedelta)
str(timedelta)
timedelta.__repr__()
timedelta.__str__()

from datetime import timedelta
td = timedelta(days=3, hours=0.5, milliseconds=123)
# 將日期時間差值轉換為字串
str(td)
'3 days, 0:30:00.123000'
td.__repr__()
'datetime.timedelta(days=3, seconds=1800, microseconds=123000)'

Python datetime 模組的 timedelta 物件與布林型別

對於 Pythondatetime模組的timedelta物件,如果其表示的日期時間差值不為0,那麽物件將被視為真(True),否則將被視為假(False)。

from datetime import timedelta
# 日期時間差值為 0 則等價於 False
bool(timedelta(days=1, hours=-24))
False
bool(timedelta())
False
# 日期時間差值不為 0 則等價於 True
bool(timedelta(microseconds=1))
True