HOWTO · Python

Pythonで datetime を減算する方法

Pythonで2つの datetime オブジェクトを減算し、経過時間を秒・分・時間などに換算する方法を説明します。

このページの内容

later - earlier のように、一方の datetime オブジェクトからもう一方を引きます。Python は2つの値の間の経過時間を表す timedelta を返します。経過時間は日数と秒数で確認でき、合計秒数や分数、時間数にも換算できます。

Pythonで datetime モジュールを使って datetime を減算する

datetime モジュールには、日付と時刻を扱うオブジェクトが用意されています。各値は年、月、日を指定して作成し、時、分、秒、マイクロ秒は必要に応じて指定できます。次の例では固定値を使うため、実行する時刻によって結果が変わりません。

from datetime import datetime

earlier = datetime(2024, 5, 1, 9, 0)
later = datetime(2024, 5, 1, 11, 30)
duration = later - earlier

print(duration)
print(duration.total_seconds())
print(duration.total_seconds() / 60)
print(duration.total_seconds() / 3600)
2:30:00
9000.0
150.0
2.5

結果は2時間30分を表す timedelta です。days、seconds、microseconds 属性は、正規化された時間差を各部分に分けて示します。経過時間の合計秒数を得るには、datetime ではなく timedelta の total_seconds() を呼び出します。その値を60で割ると分、3,600で割ると時間に換算できます。時間差が分や時間の整数倍でない場合、割り算の結果には端数が残ります。

days 属性は日数の整数部分、seconds 属性は正規化された時間差に残る秒数です。どちらも時間差全体の秒数を表すものではありません。たとえば1日を超える時間差でも、seconds は86,400未満になることがあります。期間全体の秒数が必要なら total_seconds() を使ってください。マイクロ秒を含む場合、戻り値は浮動小数点数になることがあります。

整数単位が必要な場合は、どのように丸めるかを明示してください。int() による変換はゼロ方向への切り捨てであり、最も近い単位への丸めではありません。また、1年の長さは一定ではありません。365日を1年とみなすのは近似にすぎず、うるう年や暦月の境界によって暦上の計算結果は変わります。「1年後」のように日付そのものを扱う場合は、経過秒数ではなく、暦に基づく方法を明示して計算してください。

減算する2つの値は、一貫した基準で比較できる必要があります。タイムゾーン情報を持たない naive 値同士は減算できます。タイムゾーン情報を持つ aware 値で、タイムゾーンの切り替わりをまたぐ経過時間を求める場合は、両方を astimezone(timezone.utc) で UTC に正規化します。naive 値と aware 値を混在させると TypeError が発生します。減算の前に、タイムゾーン情報を適切に設定または変換してください。