Question

I have a date range that I would like to be able to loop through in reverse. Give the following, how would I accomplish this, the standard Range operator doesn't seem t be working properly.

>> sd = Date.parse('2010-03-01')
=> Mon, 01 Mar 2010
>> ed = Date.parse('2010-03-05')
=> Fri, 05 Mar 2010
>> (sd..ed).to_a
=> [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar     2010]
>> (ed..sd).to_a
=> []

as you can see, the range operator works properly form start to end, but not from end to start.

Was it helpful?

Solution

Try upto/downto :

irb(main):003:0> sd = Date.parse('2010-03-01')
=> #<Date: 4910513/2,0,2299161>
irb(main):004:0> ed = Date.parse('2010-03-15')
=> #<Date: 4910541/2,0,2299161>
irb(main):005:0> sd.upto(ed) { |date| puts date }
2010-03-01
2010-03-02
2010-03-03
2010-03-04
2010-03-05
2010-03-06
2010-03-07
2010-03-08
2010-03-09
2010-03-10
2010-03-11
2010-03-12
2010-03-13
2010-03-14
2010-03-15
=> #<Date: 4910513/2,0,2299161>
irb(main):006:0> ed.downto(sd) { |date| puts date }
2010-03-15
2010-03-14
2010-03-13
2010-03-12
2010-03-11
2010-03-10
2010-03-09
2010-03-08
2010-03-07
2010-03-06
2010-03-05
2010-03-04
2010-03-03
2010-03-02
2010-03-01
=> #<Date: 4910541/2,0,2299161>

OTHER TIPS

I usually just reverse the resulting array:

ruby-1.8.7-p72 > sd = Date.parse('2010-03-01')
 => Mon, 01 Mar 2010 
ruby-1.8.7-p72 > ed = Date.parse('2010-03-05')
 => Fri, 05 Mar 2010 
ruby-1.8.7-p72 > (sd..ed).to_a
 => [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar 2010] 
ruby-1.8.7-p72 > (sd..ed).to_a.reverse
 => [Fri, 05 Mar 2010, Thu, 04 Mar 2010, Wed, 03 Mar 2010, Tue, 02 Mar 2010, Mon, 01 Mar 2010] 

I guess, to make it do the right thing when you don't know if the start date is going to be before or after the end date, you'd want something along the lines of:

def date_range(sd, ed)
  sd < ed ? (sd..ed).to_a : (ed..sd).to_a.reverse
end

which will give you the right thing either way:

ruby-1.8.7-p72 > sd = Date.parse('2010-03-01')
 => Mon, 01 Mar 2010 
ruby-1.8.7-p72 > ed = Date.parse('2010-03-05')
 => Fri, 05 Mar 2010 
ruby-1.8.7-p72 > date_range(sd, ed)
 => [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar 2010] 
ruby-1.8.7-p72 > date_range(ed, sd)
 => [Fri, 05 Mar 2010, Thu, 04 Mar 2010, Wed, 03 Mar 2010, Tue, 02 Mar 2010, Mon, 01 Mar 2010] 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top