前回の記事で日付の加算の話を書いたので今回は差分の話を書こうという記事です。
ドキュメントはこちらですかね。
参考: datetime
— 基本的な日付型および時間型
Pythonの日付オブジェクト(datetime) は普通に引き算ができ、timedeltaオブジェクトを返してきます。
from datetime import datetime
dt1 = datetime(2021, 11, 25, 8, 0, 0)
print(dt1)
# 2021-11-25 08:00:00
dt2 = datetime(2021, 11, 10, 15, 0, 0)
print(dt2)
# 2021-11-10 15:00:00
# datetimeオブジェクトは引き算ができる
dt_delta = dt1 - dt2
# 引き算の戻り値はtimedeltaオブジェクト
print(type(dt_delta))
# <class 'datetime.timedelta'>
# 引き算の結果の表示
print(dt_delta)
# 14 days, 17:00:00
上の例で言えば二つの日付の差分は14日と17時間であることがわかりますね。
プログラムにおいて、この14日や17時間という情報を取り出したくなることがあります。
timedelta オブジェクトは、days (日数) と second (秒数) を属性として持っているのでそれが使えます。(実際はこの他にも microseconds というのも持ってます。元の時刻がマイクロ秒単位で計測してる場合はこれも使えます。)
print(dt_delta.days)
# 14
print(dt_delta.seconds)
# 61200
# 時間数が必要なら60*60=3600で割る
print(dt_delta.seconds/3600)
# 17.0
また、total_seconds() というメソッドもあり、これを使うと日付の差分の総秒数が得られます。こちらはマイクロ秒の情報も小数で得られます。整数部分は秒数です。
print(dt_delta.total_seconds())
# 1270800.0
# 以下の計算結果と同じ
dt_delta.days * 60 * 60 * 24 + dt_delta.seconds
# 1270800
日付の差分がマイナスになる場合は少し注意が必要です。
days は負の値になりますが、 secondsは正の値になります。
14日と17時間、の符号反転が -15日と7時間 になるわけですね。
print(dt1)
# 2021-11-25 08:00:00
print(dt2)
# 2021-11-10 15:00:00
# マイナスになる差分
dt_delta2 = dt2-dt1
print(dt_delta2)
# -15 days, 7:00:00
print(dt_delta2.days)
# -15
print(dt_delta2.seconds)
# 25200 (= 7*60*60)
このマイナス日付と正の時間という組み合わせが使いにくいと感じる場合、組み込み関数のabs(絶対値)で符合反転させることもできます。
print(abs(dt_delta2))
# 14 days, 17:00:00
ここまで datetime オブジェクト(日時)の話をしてきましたが、date(日付)オブジェクトでも話は同様です。普通に引き算ができ、timedelta オブジェクトが帰ってきます。
0しか入ってきませんがsecond属性も持ってます。
from datetime import date
date1 = date(2021, 11, 25)
print(date1)
# 2021-11-25
date2 = date(2021, 11, 10)
print(date2)
# 2021-11-10
# datetimeオブジェクトは引き算ができる
date_delta = date1 - date2
# 引き算の戻り値はtimedeltaオブジェクト
print(type(date_delta))
# <class 'datetime.timedelta'>
# 引き算の結果の表示
print(date_delta)
# 15 days, 0:00:00
print(date_delta.days)
# 15
print(date_delta.seconds)
# 0
datetimeライブラリには、datetmeやdateの他に、timeというオブジェクトもありますが、実はこのtimeについては差分が取れません。これは気をつけましょう。
from datetime import time
time1 = time(15, 30, 20)
print(time1)
# 15:30:20
time2 = time(8, 20, 14)
print(time2)
# 08:20:14
# timeオブジェクトは引き算できない
try:
time_delta = time1 - time2
except Exception as e:
print(e)
# unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
ちなみに、datetimeとdateを引き算することもできません。
date1 = date(2021, 11, 25)
print(date1)
# 2021-11-25
dt1 = datetime(2021, 11, 25, 10, 00, 00)
print(dt1)
# 2021-11-25 10:00:00
try:
dt1 - date1
except Exception as e:
print(e)
# unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'
時刻がからむ差分を取るときは、型をdatetimeに揃えて行うようにしましょう。