Pythonでdatetimeモジュールを使って日付、時刻の計算をする基本について解説します。
Contents
datetimeモジュールの計算の基本
datetimeモジュールを用いた日付の加算・減算などの計算の基本について紹介します。
本記事では、日付、時刻の計算に焦点を当てて説明しています。datetimeモジュールを用いた日付や時刻の取得、生成といった基本的な使い方については「日付、時刻を扱う基本」で説明してますのであわせて参考にしてもらえればと思います。
日付・時刻の加算・減算
datetimeモジュールでは「+」「-」といった演算子を定義しているため、日付や時刻を簡単に加算、減算することができます。
基本的な計算方法
datetimeやdateの加算や減算は、時間差分を表現するdatetime.timedeltaを使用することで簡単に計算できます。
以下の簡単な例で、日付や時刻の加算、減算について見てみましょう。
import datetime # ===== datetimeの加算や減算 dt = datetime.datetime(2022, 1, 1, 0, 0, 0, 0) # 加算する dt_plus = dt + datetime.timedelta(weeks=1, days=5, hours=10) # 減算する dt_minus = dt - datetime.timedelta(weeks=1, days=5, hours=10) print("=== datetimeの加算や減算") print(dt) print(dt_plus) print(dt_minus) # ===== dateの加算や減算 d = datetime.date(2021, 1, 1) # 加算する d_plus = d + datetime.timedelta(weeks=1, days=5) # 減算する d_minus = d - datetime.timedelta(weeks=1, days=5) print("=== dateの加算や減算") print(d) print(d_plus) print(d_minus)
【実行結果例】 === datetimeの加算や減算 2022-01-01 00:00:00 2022-01-13 10:00:00 2021-12-19 14:00:00 === dateの加算や減算 2021-01-01 2021-01-13 2020-12-20
上記のように時間の加算分、減算分はtimedeltaを用います。
timedeltaを生成するときの引数としては、weeks(週数)、days(日数)、hours(時間数)、minitus(分数)、seconds(秒数)、milliseconds(ミリ秒)、microseconds(マイクロ秒)といった値をキーワード引数として指定することが可能です。
[注意点] timeの加算や減算
timeの加算や減算はTypeErrorとなる
timeの時間の加算や減算をしたい場合にも、datetimeやdateと同じようにdatetime.timedeltaを使用すればよいと思ってしまいますが、同じようにコーディングすると以下のようにエラーとなってしまいます。
# timeのみの加算、減算はできない import datetime t = datetime.time(0, 0, 0) # 加算する t_plus = t + datetime.timedelta(hours=1, minutes=30, seconds=30) # 減算する t_minus = t - datetime.timedelta(hours=1, minutes=30, seconds=30)
【実行結果】 TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta'
上記のようにTypeErrorとなり、timedeltaを使用した加算や減算をすることはできません。
timeの加算や減算の解決策
timeで加算や減算ができないことへの解決策としては、timeをdatetimeに変換してtimedeltaを使用する方法があります。以下例で見てみましょう。
import datetime # 仮の日付を作成する dt = datetime.datetime(2022, 1, 1) # timeをdatetimeに変換する t = datetime.datetime.combine(dt, datetime.time(0, 0, 0)) # 加算する t_plus = t + datetime.timedelta(hours=1, minutes=30, seconds=30) # 減算する t_minus = t - datetime.timedelta(hours=1, minutes=30, seconds=30) print("=== timeの加算や減算") # timeクラスとして使用したい場合 print(datetime.time(t.hour, t.minute, t.second)) print(datetime.time(t_plus.hour, t_plus.minute, t_plus.second)) print(datetime.time(t_minus.hour, t_minus.minute, t_minus.second)) # 文字列として時刻を使用する場合 print(t.strftime("%H:%M:%S")) print(t_plus.strftime("%H:%M:%S")) print(t_minus.strftime("%H:%M:%S"))
【実行結果】 === timeの加算や減算 00:00:00 01:30:30 22:29:30 00:00:00 01:30:30 22:29:30
上記の例のように任意日付のdatetimeを作成し、datetime.combineメソッドで対象とするtimeクラスのインスタンスと結合をすることで目的のtimeをdatetime型にします。その後は、datetimeやdateで見てきたようなtimedeltaを用いた加算、減算をすることができます。
この方法で得られる値はdatetime型で、不要な日付の部分も含めてしまっているため、その後timeとして扱いたいのであれば、time型に変換すればよいです。また、strで扱いたいのであれば、strftimeメソッドでフォーマットを指定して文字列に変換することができます。
日付・時刻の差分計算
上記ではdaimedeltaを使って一定の期間を加算・減算するような例を見てきました。datetimeモジュールにて定義されているインスタンス同士は「-」演算子を用いることで差分を計算することができます。
基本的な計算方法
以下の簡単な例で、日付や時刻の差分計算について見てみましょう。
import datetime # ===== datetimeの差分 dt1 = datetime.datetime(2022, 3, 1, 18, 30, 45, 500) dt2 = datetime.datetime(2022, 1, 1, 12, 15, 15, 250) # 差分を求める dt_diff = dt1 - dt2 print("=== datetimeの差分") print(dt_diff) print(type(dt_diff)) print(dt_diff.days) print(dt_diff.seconds) # ===== dateの差分 d1 = datetime.date(2022, 3, 1) d2 = datetime.date(2022, 1, 1) # 差分を求める d_diff = d1 - d2 print("=== dateの差分") print(d_diff) print(type(d_diff)) print(d_diff.days) print(d_diff.seconds)
【実行結果】 === datetimeの差分 59 days, 6:15:30.000250 <class 'datetime.timedelta'> 59 22530 === dateの差分 59 days, 0:00:00 <class 'datetime.timedelta'> 59 0
上記のように「-」演算子を使用するだけで簡単に日付、時刻の差分を求めることができます。typeで確認している通り差分結果はdatetime.timedeltaクラスのインスタンスとなります。timedeltaはprintすると時間間隔を表示することができます。
また、差分のtimedeltaに対して、daysやsecondsを確認することで日数や秒数として時間間隔といった要素を抽出することが可能です。
[注意点] timeの差分計算
timeの差分計算はTypeErrorとなる
前述の加算、減算の時と同じようにtimeについては直接差分を計算することができません。time型同士で差分を取ろうとすると以下のようなエラーとなります。
# time同士の差分をとることはできない import datetime t1 = datetime.time(12, 30, 30) t2 = datetime.time(0, 0, 0) # 差分を求める t_diff = t1 - t2
【実行結果】 TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'
timeの差分計算の解決策
timeで差分計算解決策としては、timeをdatetimeに変換してから差分をとる方法があります。以下例で見ていきましょう。
import datetime # 仮の日付を作成する dt = datetime.datetime(2022, 1, 1) # timeをdatetimeに変換する t1 = datetime.datetime.combine(dt, datetime.time(12, 0, 0)) t2 = datetime.datetime.combine(dt, datetime.time(0, 0, 0)) # 差分を求める t_diff = t1 - t2 print("=== timeの差分") print(t_diff) print(type(t_diff)) print(t_diff.days) print(t_diff.seconds)
【実行結果】 === timeの差分 12:00:00 <class 'datetime.timedelta'> 0 43200
上記の例のように任意日付のdatetimeを作成します。その後、datetime.combineメソッドで、対象とするtimeクラスのインスタンスと結合をすることで目的のtimeをdatetime型に変換します。その後は、対象の差分を「-」で計算することができます。
日付・時刻の比較をする
datetimeモジュールにて定義されているクラスであるdatetime, date, time同士は、「<」「>」といった比較演算子を用いることで比較をすることができます。
以下の簡単な例で、日付、時刻の比較方法について見てみましょう。
import datetime # ===== datetimeの比較 dt1 = datetime.datetime(2022, 1, 1, 0, 0, 0, 0) dt2 = datetime.datetime(2022, 3, 1, 12, 30, 30, 0) # 日時を比較する print("=== datetimeの比較") print(dt1 < dt2) print(dt1 > dt2) # ===== dateの比較 d1 = datetime.date(2021, 2, 1) d2 = datetime.date(2021, 3, 1) # 日付を比較する print("=== dateの比較") print(d1 < d2) print(d1 > d2) # ===== timeの比較 t1 = datetime.time(0, 0, 0) t2 = datetime.time(12, 30, 30) # 時刻を比較する print("=== timeの比較") print(t1 < t2) print(t1 > t2)
【実行結果】 === datetimeの比較 True False === dateの比較 True False === timeの比較 True False
上記のようにdatetime、date、time同士を比較するとTrue、Falseが返却されます。日付を使用したif文の条件判定等で使用することができます。
まとめ
datetimeモジュールを用いた日付の加算・減算などの計算の基本について紹介しました。
datetimeモジュールでは「+」「-」といった演算子を定義しているため、日付や時刻を簡単に加算、減算することができます。また、「<」「>」といった比較演算子を用いることで比較をすることも可能です。
timeの計算をする際にはそのままで計算するとエラーになりますので、必要に応じてdatetimeへ変換したりtimedeltaを使用したりすることで対応できます。
日付、時刻の計算はプログラムしているとよく使うと思うので是非使い方を覚えてもらえたらなと思います。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。
datetimeモジュールの公式ドキュメントはこちらを参照してください。