Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Loop Through a Date Range in Reverse?

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.

like image 802
Russ Bradberry Avatar asked May 14 '10 18:05

Russ Bradberry


People also ask

How do I iterate over a date range in Python?

We can use the date_range() function method that is available in pandas. It is used to return a fixed frequency DatetimeIndex. We can iterate to get the date using date() function.


2 Answers

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> 
like image 93
Joseph Weissman Avatar answered Oct 13 '22 07:10

Joseph Weissman


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]  
like image 34
Graeme Mathieson Avatar answered Oct 13 '22 07:10

Graeme Mathieson