🎉
Rubyで2つの時間が重なっているか比較を行う方法
Rubyで2つの時間が重なっているか比較を行う方法
やりたいこと
時間A(9:00〜11:00)と、時間B(10:00〜12:00)が少しでも重なっているか、boolで取得したい。
結論
まずは結論から。
冗長に書きます。適宜短くしてください。
# 比較したい時間たちを、INTに変換
time_a_start = time_to_int('9:00')
time_a_end = time_to_int('11:00')
time_b_start = time_to_int('10:00')
time_b_end = time_to_int('12:00')
# 範囲オブジェクトに成形
time_a = time_a_start..time_a_end
time_b = time_b_start..time_b_end
# 重なりの結果を、boolで取得
# cover?が使えるなら
(time_a).cover?(time_b) # => true
# 使えないなら
range_include?(time_a, time_b) # => true
# 時間をINT型に変換するメソッド
def time_to_int(time)
if time.class == String
time.gsub(':','').to_i
else
time.strftime('%H%M').to_i
end
end
# 2つの範囲オブジェクトの重なりをチェックするメソッド
def range_include?(r1, r2)
(r1.max >= r2.min && r2.max >= r1.min) ? true:false
end
注意点
タイムゾーンには気をつけましょう(n敗)
解説
先ほど使ったメソッドの解説
時間をINT型に変換するメソッド
def time_to_int(time)
if time.class == String
time.gsub(':','').to_i
else
time.strftime('%H%M').to_i
end
end
Stringオブジェクトでも、TIMEオブジェクトでもINTに変換できるようにしています。
冗長ですが、そろってないことも多かったので。
time_to_int('10:30') #=> 1030
time_to_int(Time.now) #=> 1030
時間は必ず0:00 -> 23:59 と増えていくので、INTにしちゃえばRangeに変換して、簡単に比較できるということです。
2つの範囲オブジェクトの重なりをチェックするメソッド
cover? メソッドが使えるなら、そのまま使えばOKです。
使えない場合は、下記の記事で解説されている方法がオススメです。
# 2つの範囲オブジェクトの重なりをチェックするメソッド
def range_include?(r1, r2)
(r1.max >= r2.min && r2.max >= r1.min) ? true:false
end
以上
書いた経緯
二つの時間範囲が重なっているかをチェックしたくて調べた際、ピンポイントに解決してくれる記事がみあたらなかったので、とりあえず忘備録として残します。
Discussion