PIYO - Tech & Life -

期間を表すRangeオブジェクトが便利

Tips Ruby

Rubyで日付・日時を扱うときはDateTimeなどのクラスを使いますよね。これらのインスタンスは不等号で大小を比較できるようになっています。

あるDateTimeインスタンスが指定した期間に含まれるか、というようなことを調べたいときはRubyのRangeクラスが使えます。というか、Rangeクラスにしておくと便利です。

s = DateTime.new(2014, 1, 1)
e = DateTime.now

range = s..e
range.class # => Range

date = DateTime.new(2014, 1, 10)
range.cover?(date) # => true

range.include?(date) # => TypeError

range.cover?(DateTime.new(2013, 12, 30)) # => false

range.include?(date)とすると例外が発生するようです。日付のRangeに対してinclude?は使えません。そのかわりにcover?が使えます。用途としてはこちらで問題なし。

include?cover?の違い

include?

引数となった値がRange内の要素と一致する場合にtrueとなります。

range = "a".."c"

range.include?("b") # => true
range.include?("bb") # => false

range.to_a # => ["a", "b", "c"] 

cover?

引数がRangeの両端の値の範囲ないにあればtrueとなります。

range = "a".."c"

range.cover?("b") # => true
range.cover?("bb") # => true

range.cover?("bb")trueになるというのが特徴的です。

"bb"はrangeに含まれる要素(range.to_aに含まれる要素)ではありませんのでinclude?ではfalseが返りますが、cover?では"bb""a""c"と比較して"a" <= "bb" <= "c"になるかどうかを調べるのでtrueとなるわけです。