我有一个日期范围(从,到),我希望循环通过不同的间隔(每日,每周,每月,...)
我如何遍历此日期范围?
更新
感谢您的回答,我想出了以下内容:
interval = 'week' # month, year
start = from
while start < to
stop = start.send("end_of_#{interval}")
if stop > to
stop = to
end
logger.debug "Interval from #{start.inspect} to #{stop.inspect}"
start = stop.send("beginning_of_#{interval}")
start += 1.send(interval)
end
这将循环显示间隔为周,月或年的日期范围,并且考虑给定间隔的开始和结束。
由于我在我的问题中没有提到这一点,所以我选择了能够将我推向正确方向的答案。
答案 0 :(得分:7)
循环直到from
日期加上1.day
,1.week
或1.month
大于to
日期?
> from = Time.now
=> 2012-05-12 09:21:24 -0400
> to = Time.now + 1.month + 2.week + 3.day
=> 2012-06-29 09:21:34 -0400
> tmp = from
=> 2012-05-12 09:21:24 -0400
> begin
?> tmp += 1.week
?> puts tmp
?> end while tmp <= to
2012-05-19 09:21:24 -0400
2012-05-26 09:21:24 -0400
2012-06-02 09:21:24 -0400
2012-06-09 09:21:24 -0400
2012-06-16 09:21:24 -0400
2012-06-23 09:21:24 -0400
2012-06-30 09:21:24 -0400
=> nil
答案 1 :(得分:6)
在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方法添加到my personal core_extensions
"gem"。如果您想在Rails项目中使用它,只需将以下内容添加到您的Gemfile:
gem 'core_extensions', github: 'pdobb/core_extensions'
答案 2 :(得分:4)
succ方法在1.9范围内已弃用。想要在一周内做同样的事情,我来到这个解决方案:
def by_week(start_date, number_of_weeks)
number_of_weeks.times.inject([]) { |memo, w| memo << start_date + w.weeks }
end
这会在间隔中返回一周的数组。几个月可轻松适应。
答案 3 :(得分:0)
您在Range对象上有step方法。 http://ruby-doc.org/core-1.9.3/Range.html#method-i-step