1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rubyの連続でない時間帯に含むかを判断

Last updated at Posted at 2021-07-08

TL;DR

delta = 10.minute
schedule = %w[10:00 12:00 14:00 16:00 18:00]

time_ranges = schedule.map do |t|
  (Time.parse(t) - delta)..(Time.parse(t) + delta)
end

case Time.now
when *time_ranges
  p "範囲内です"
else
  p "範囲外でござる"
end

経緯

とある要望で現在の時間が指定の時間帯に含まれるかをチェックする必要がありました。
例:

現在時刻が10:00、12:00、14:00、16:00、18:00の前後10分の区間内に含むかを判断せよ

大人しくIF文を組むのもいいですが、上記スケジュールもいつか変数になると考え、拡張性のある上手い書き方があるか考えました。

解説

レガシーなbetween?

SQLもそうですが、含むか含まないかを判断するには、Betweenが王道でした。
もちろん、RubyにもBetweenができますが、下記のように、1つのBetweenは1つの区間しか対応できません。

Time.now.between?(Time.parse('10:00'), Time.parse('18:00'))

case..when記法の活用

Rubyのcase..when記法は、以下のメリットがあります。

  • 複数条件が書けます。 Eg: when 1,3,5,7
  • 範囲(Range)に対応します。 Eg: when 1..5
  • 条件は配列の展開式にも対応します。 Eg: when *[5,10,15]

上記仕様を利用すれば、簡単に連続でない不特定の区間を判定できます。

# まずはRangeリストを組むこと
# Railsではない時
require 'time' 
delta = 10 * 60

# Railsの時
delta = 10.minute

time_ranges = %w[10:00 12:00 14:00 16:00 18:00].map do |t|
  (Time.parse(t) - delta)..(Time.parse(t) + delta)
  # <含む...含まない> にしたい時は `...` を使うこと
end

=> [2021-07-09 09:50:00 +0900..2021-07-09 10:10:00 +0900,
 2021-07-09 11:50:00 +0900..2021-07-09 12:10:00 +0900,
 2021-07-09 13:50:00 +0900..2021-07-09 14:10:00 +0900,
 2021-07-09 15:50:00 +0900..2021-07-09 16:10:00 +0900,
 2021-07-09 17:50:00 +0900..2021-07-09 18:10:00 +0900]
# あとは上記Rangeリストを `case..when` 文に組み込むこと

case Time.now
when *time_range_list
  p "範囲内です"
else
  p "範囲外でござる"
end

参考

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?