Ruby 1.9 では、時間範囲をステップ実行するために Range に独自のメソッドを追加しました。
class Range
def time_step(step, &block)
return enum_for(:time_step, step) unless block_given?
start_time, end_time = first, last
begin
yield(start_time)
end while (start_time += step) <= end_time
end
end
次に、これを次のように呼び出すことができます (私の例では Rails 固有のメソッドを使用しています: 15.minutes):
irb(main):001:0> (1.hour.ago..Time.current).time_step(15.minutes) { |time| puts time }
2012-07-01 21:07:48 -0400
2012-07-01 21:22:48 -0400
2012-07-01 21:37:48 -0400
2012-07-01 21:52:48 -0400
2012-07-01 22:07:48 -0400
=> nil
irb(main):002:0> (1.hour.ago..Time.current).time_step(15.minutes).map { |time| time.to_s(:short) }
=> ["01 Jul 21:10", "01 Jul 21:25", "01 Jul 21:40", "01 Jul 21:55", "01 Jul 22:10"]
このメソッドは、ブロックが指定されていない場合に列挙メソッドが列挙子を返すという Ruby 1.9 規則を使用していることに注意してください。これにより、列挙子を一緒に並べることができます。
アップデート
Range#time_step メソッドを個人的なcore_extensions
"gem"に追加しました。これを Rails プロジェクトで利用したい場合は、以下を Gemfile に追加してください:
gem 'core_extensions', github: 'pdobb/core_extensions'