Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate every month with date objects

Tags:

So I have two ruby Date objects, and I want to iterate them every month. For example if I have Date.new(2008, 12) and Date.new(2009, 3), it would yield me 2008-12, 2009-1, 2009-2, 2009-3 (as Date objects of course). I tried using range, but it yields every day. I saw step method for Date however it only allows me to pass number of days (and each month has different number of those). Anyone have any ideas?

like image 380
Andrius Avatar asked Nov 12 '09 19:11

Andrius


People also ask

How do you iterate over months in Python?

Method 2: rrule rrule is a package present in dateutil library and this package consists of a method also rrule which takes dtstart, until and specific time period as parameters which are start date, end date, and time period based on iteration respectively. Specific time periods are WEEKLY, MONTHLY, YEARLY, etc.

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

Here is something very Ruby:

first day of each month

(Date.new(2008, 12)..Date.new(2011, 12)).select {|d| d.day == 1}

It will give you an array of the first day for each month within the range.

last day of each month

(Date.new(2008, 12)..Date.new(2012, 01)).select {|d| d.day == 1}.map {|d| d - 1}.drop(1)

Just note that the end date needs to be the month after your end range.

like image 87
The Who Avatar answered Oct 13 '22 20:10

The Who


I find that I need to do this sometimes when generating select lists of months. The key is the >> operator on Date, which advances the Date forward one month.

def months_between(start_month, end_month)
  months = []
  ptr = start_month
  while ptr <= end_month do
    months << ptr
    ptr = ptr >> 1
  end
  months
end

results = months_between(Date.new(2008,12), Date.new(2009,3))

Of course, you can format the results however you like in the loop.

months << "#{Date::MONTHNAMES[ptr.month]} #{ptr.year}"

Will return the month name and year ("March 2009"), instead of the Date object. Note that the Date objects returned will be set on the 1st of the month.

like image 28
Jonathan Julian Avatar answered Oct 13 '22 19:10

Jonathan Julian