#はじめに
時間と時間の重なりを計算するロジックを考えていて(業務アプリケーションで)
関数が用意されているのではと思い、ネットで色々探してみたものの、
適当なものが見つからず、自作しました。
考えてみるとロジックは簡単だったので、公開します。
具体的に
例えば、
業務時間が09:00〜14:10だとして、
休み時間が、10:00〜10:20 12:00〜12:30 14:00〜14:20とあった場合
業務時間中に休み時間をとったのは、
10:00〜10:20の20分間
12:00〜12:30の30分間
14:00〜14:10の10分間
であって、合計60分間ですね。
机上で計算すると単純なのですが、いざ、プログラムを組むとなると
少し面倒な気がします。
#技術解説
def time_diff(m1, m2, n1, n2):
if not(n2 < m1 or m2 < n1 ):
td = (n2 if n2<m2 else m2) - (n1 if m1<n1 else m1)
return round(td.seconds / 60)
return 0
m1とm2は、業務時間 09:00、14:10
n1とn2は、休み時間 10:00、10:20のdatetime型をそれぞれセットします。
if not(n2 < m1 or m2 < n1 ):
まず、if notで、休憩時間が、業務時間が超えていないかをチェックします。
td = (n2 if n2<m2 else m2) - (n1 if m1<n1 else m1)
return round(td.seconds / 60)
そのあと、終了時間から開始時間を引き算して、経過時間(秒)を分に変換しています。
終了時間は、業務時間(終了)と休憩時間(終了)を比較して、より小さい方を、取得しています。
開始時間は、終了時間とは逆に、業務時間(開始)と休憩時間(開始)を比較して、より大きい方を、取得しています。
それにより、業務時間と休憩時間の重なりの開始時間と終了時間を判定しています。
#サンプルソース
import datetime
def time_diff(m1, m2, n1, n2):
if not(n2 < m1 or m2 < n1 ):
td = (n2 if n2<m2 else m2) - (n1 if m1<n1 else m1)
return round(td.seconds / 60)
return 0
dt1 = datetime.datetime.strptime('09:00', '%H:%M')
dt2 = datetime.datetime.strptime('14:10', '%H:%M')
rest1 = datetime.datetime.strptime('10:00', '%H:%M')
rest2 = datetime.datetime.strptime('10:20', '%H:%M')
rest = time_diff(dt1, dt2, rest1, rest2)
rest1 = datetime.datetime.strptime('12:00', '%H:%M')
rest2 = datetime.datetime.strptime('12:30', '%H:%M')
rest += time_diff(dt1, dt2, rest1, rest2)
rest1 = datetime.datetime.strptime('14:00', '%H:%M')
rest2 = datetime.datetime.strptime('14:20', '%H:%M')
rest += time_diff(dt1, dt2, rest1, rest2)
print(rest)
# 60
まとめ
上の技術解説では、00:00〜24:00で計算していますが、日を超える場合が、想定されるのであれば、
時刻だけでなく、年月日も含めれば、成り立つロジックになっていると思います。