Pythonで経過時間や日時(日付・時刻)の差分を測定・算出
Pythonで経過時間を測定したり、2つの日時(日付・時刻)の差分(時間差)を算出するには、標準ライブラリのtimeモジュール、datetimeモジュールを使う。経過時間や時間差は秒数や日数で表すことができる。
ここでは以下の内容について説明する。
- 経過時間を測定
- 日時(日付・時刻)の差分(時間差)を算出
datetime
オブジェクトの引き算date
オブジェクトの引き算datetime
オブジェクトとdate
オブジェクトの引き算- 現在時刻と特定の日時との時間差
- 時間差を加減した日時を取得
秒数と分・時間・日数などとの相互変換については以下の記事を参照。
- 関連記事: Pythonで秒数と分・時間・日数を相互に変換
経過時間を測定
timeモジュールのtime()
関数を使うとUNIX時間(エポック秒)を浮動小数点数float
型で取得できる。
import time
ut = time.time()
print(ut)
# 1549281692.9876952
print(type(ut))
# <class 'float'>
UNIX時間(エポック秒)はUTC(協定世界時)の1970年1月1日0時0分0秒からの経過秒数。datetime
オブジェクトなどと相互に変換できる。
time.time()
の返り値は浮動小数点数float()
で小数点以下にミリ秒マイクロ秒の情報を持つが、公式ドキュメントにあるようにその精度はシステムに依存するので注意。
時刻は常に浮動小数点数で返されますが、すべてのシステムが 1 秒より高い精度で時刻を提供するとは限らないので注意してください。
time.time() --- 時刻データへのアクセスと変換 — Python 3.7.2 ドキュメント
time.time()
を利用すると、Pythonのプログラム内で経過時間を測定できる。
開始時のUNIX時間をtime.time()
で取得して変数に格納し保持しておいて、経過時間を測定したいタイミングで再度UNIX時間を測定し差分を算出すると経過時間の秒数が求められる。
start = time.time()
time.sleep(3)
t = time.time() - start
print(t)
# 3.001929998397827
この例ではtime.sleep()
で処理を一時停止している。
なお、コードの実行時間を計測するためのtimeitというモジュールもある。自動で繰り返し測定し平均を出したりしてくれるので、処理速度の検討といった目的にはtimeitのほうが便利。
単純に処理にかかった時間をログとして残しておきたいというような用途であればtime.time()
を利用するのが適当。
測定結果の秒数を分や時間に変換したい場合は以下の記事を参照。
- 関連記事: Pythonで秒数と分・時間・日数を相互に変換
日時(日付と時刻)の差分(時間差)を算出
プログラム内で開始タイミングと終了タイミングを指定するのではなく、任意の2つの日時の差分(時間差)を算出したい場合はdatetimeモジュールを使う。
datetimeモジュールには日時(日付と時刻)を表すdatetime
型、日付を表すdate
型があるが、それらのオブジェクト同士を引き算して差分を求めると、時間差を表すtimedelta
型のオブジェクトが生成される。
datetimeモジュールの基本的な内容については以下の記事を参照。
datetimeオブジェクトの引き算
datetime
オブジェクトの場合。
import datetime
dt1 = datetime.datetime(year=2017, month=10, day=10, hour=15)
print(dt1)
# 2017-10-10 15:00:00
print(type(dt1))
# <class 'datetime.datetime'>
dt2 = datetime.datetime(year=2019, month=1, day=1, hour=12)
print(dt2)
# 2019-01-01 12:00:00
td = dt2 - dt1
print(td)
# 447 days, 21:00:00
print(type(td))
# <class 'datetime.timedelta'>
timedelta
オブジェクトは日数、秒数、マイクロ秒数の情報を持ち、属性days
, seconds
, microseconds
でアクセスできる。また、total_seconds()
メソッドでトータルの秒数を取得することも可能。
print(td.days)
# 447
print(td.seconds)
# 75600
print(td.microseconds)
# 0
print(td.total_seconds())
# 38696400.0
秒を分や時間に変換したい場合は以下の記事を参照。
- 関連記事: Pythonで秒数と分・時間・日数を相互に変換
timedelta
オブジェクトは引き算の順番によって負の値になる場合がある。負のtimedelta
オブジェクトはdays
が負でseconds
とmicroseconds
は正になる。
td_m = dt1 - dt2
print(td_m)
# -448 days, 3:00:00
print(td_m.days)
# -448
print(td_m.seconds)
# 10800
print(td_m.total_seconds())
# -38696400.0
timedelta
オブジェクトに対しても組み込み関数abs()
が有効。単純に時間差の日数や秒数を取得したい場合はabs()
を使うと引き算の順番を考慮しなくてもよいので便利。
td_abs = abs(dt1 - dt2)
print(td_abs)
# 447 days, 21:00:00
print(td_abs.days)
# 447
print(td_abs.seconds)
# 75600
print(td_abs.total_seconds())
# 38696400.0
dateオブジェクトの引き算
date
オブジェクトでも同様。
d1 = datetime.date(year=2017, month=10, day=10)
print(d1)
# 2017-10-10
print(type(d1))
# <class 'datetime.date'>
d2 = datetime.date(year=2019, month=1, day=1)
print(d2)
# 2019-01-01
td = abs(d1 - d2)
print(td)
# 448 days, 0:00:00
print(type(td))
# <class 'datetime.timedelta'>
datetimeオブジェクトとdateオブジェクトの引き算
datetime
オブジェクトとdate
オブジェクトの引き算はエラーとなる。
# print(dt2 - d1)
# TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'
どちらかの型に揃える必要がある。
datetime
オブジェクトはdate()
メソッドでdate
オブジェクトに変換可能。時刻の情報は失われる。
print(dt2.date())
# 2019-01-01
print(type(dt2.date()))
# <class 'datetime.date'>
print(dt2.date() - d1)
# 448 days, 0:00:00
datetime.combine()
でdate
オブジェクトとtime
オブジェクトからdatetime
オブジェクトを生成できる。
time
オブジェクトはコンストラクタで生成可能。コンストラクタの引数を省略すると00:00:00
になる。任意の時刻にしたい場合は引数hour
, minute
, second
, microsecond
を指定すればよい。
print(datetime.datetime.combine(d1, datetime.time()))
# 2017-10-10 00:00:00
print(type(datetime.datetime.combine(d1, datetime.time())))
# <class 'datetime.datetime'>
print(dt2 - datetime.datetime.combine(d1, datetime.time()))
# 448 days, 12:00:00
現在時刻と特定の日時との時間差
現在時刻のdatetime
オブジェクトやdate
オブジェクトはdatetime.now()
やdate.today()
で取得できる。
- 関連記事: Pythonで現在時刻・日付・日時を取得
それらを利用すると現在時刻と特定の日時との差分を算出できる。
print(datetime.datetime.now() - dt2)
# 34 days, 9:30:07.362784
print(datetime.date.today() - d2)
# 34 days, 0:00:00
過去の日時とでも未来の日時とでも比較できる。上述のように、絶対値として時間差を取得したい場合はabs()
を使う。
時間差を加減した日時を取得
timedelta
オブジェクトはdatetime
オブジェクトやdate
オブジェクトと引き算や足し算などの演算が可能。例えば、1週間前や10日後の日付、50分後の時刻などを簡単に計算して取得できる。
任意の時間差はtimedelta
オブジェクトのコンストラクタに日数や時間、秒数などを指定して生成できる。
指定できるのはweeks
, days
, hours
, minutes
, seconds
, milliseconds
(ミリ秒), microseconds
(マイクロ秒)。省略すると0
となる。日数が固定ではない月と年は指定できない。
td = datetime.timedelta(weeks=1, hours=20)
print(td)
# 7 days, 20:00:00
print(type(td))
# <class 'datetime.timedelta'>
これをdatetime
オブジェクトやdate
オブジェクトとの演算に使用する。
print(dt1)
# 2017-10-10 15:00:00
print(dt1 + td)
# 2017-10-18 11:00:00
print(dt1 - td)
# 2017-10-02 19:00:00
date
オブジェクトとの演算の場合、timedelta
オブジェクトの時刻の情報は無視されるので注意。
print(d1)
# 2017-10-10
print(d1 + td)
# 2017-10-17
print(d1 - td)
# 2017-10-03