@CaptainPete のベースを使用して、ActiveSupport::DateTime#advance
呼び出しを使用するように変更しました。`:month" や ":year" のように時間間隔が不均一な場合、違いが有効になります。
require 'active_support/all'
class RailsDateRange < Range
# step is similar to DateTime#advance argument
def every(step, &block)
c_time = self.begin.to_datetime
finish_time = self.end.to_datetime
foo_compare = self.exclude_end? ? :< : :<=
arr = []
while c_time.send( foo_compare, finish_time) do
arr << c_time
c_time = c_time.advance(step)
end
return arr
end
end
# Convenience method
def RailsDateRange(range)
RailsDateRange.new(range.begin, range.end, range.exclude_end?)
end
私のメソッドも を返しますArray
。比較のために、@CaptainPete の回答も配列を返すように変更しました。
時間別
RailsDateRange((4.years.ago)..Time.now).every(years: 1)
=> [Tue, 13 Oct 2009 11:30:07 -0400,
Wed, 13 Oct 2010 11:30:07 -0400,
Thu, 13 Oct 2011 11:30:07 -0400,
Sat, 13 Oct 2012 11:30:07 -0400,
Sun, 13 Oct 2013 11:30:07 -0400]
DateRange((4.years.ago)..Time.now).every(1.year)
=> [2009-10-13 11:30:07 -0400,
2010-10-13 17:30:07 -0400,
2011-10-13 23:30:07 -0400,
2012-10-13 05:30:07 -0400,
2013-10-13 11:30:07 -0400]
月ごと
RailsDateRange((5.months.ago)..Time.now).every(months: 1)
=> [Mon, 13 May 2013 11:31:55 -0400,
Thu, 13 Jun 2013 11:31:55 -0400,
Sat, 13 Jul 2013 11:31:55 -0400,
Tue, 13 Aug 2013 11:31:55 -0400,
Fri, 13 Sep 2013 11:31:55 -0400,
Sun, 13 Oct 2013 11:31:55 -0400]
DateRange((5.months.ago)..Time.now).every(1.month)
=> [2013-05-13 11:31:55 -0400,
2013-06-12 11:31:55 -0400,
2013-07-12 11:31:55 -0400,
2013-08-11 11:31:55 -0400,
2013-09-10 11:31:55 -0400,
2013-10-10 11:31:55 -0400]
年別
RailsDateRange((4.years.ago)..Time.now).every(years: 1)
=> [Tue, 13 Oct 2009 11:30:07 -0400,
Wed, 13 Oct 2010 11:30:07 -0400,
Thu, 13 Oct 2011 11:30:07 -0400,
Sat, 13 Oct 2012 11:30:07 -0400,
Sun, 13 Oct 2013 11:30:07 -0400]
DateRange((4.years.ago)..Time.now).every(1.year)
=> [2009-10-13 11:30:07 -0400,
2010-10-13 17:30:07 -0400,
2011-10-13 23:30:07 -0400,
2012-10-13 05:30:07 -0400,
2013-10-13 11:30:07 -0400]