Rails, ActiveRecord, and time ranges

11 Feb 2009

On my military reading list site I wanted to be able to find records created in a particular month. That let me do URLs like /revisions/navy/jan-2009 and then look up the proper revision - e.g., the 2009 revision of the Navy reading list.

So, here are the functions, the first of which I got from some place on the internet which now eludes my Googling:

def days_in_month(d)
  (Date.new(d.year,12,31) << (12-d.month)).day
end

def beginning_to_end_of_month(date)
  from = date - ((date.day-1).days)
  to = from + (days_in_month(from)-1).days + 1.day
  from..to
end

And here's how to use them to look up revisions created in Januaary 2009:

>> Revision.find(:all, 
 :conditions => 
  {:created_at => 
  beginning_to_end_of_month(Date.parse("jan 2009"))})
=> [#<Revision id: 1, reading_list_id: 3, 
 created_at: "2009-01-10 21:25:17", 
 updated_at: "2009-01-10 21:25:17">, 
 #<Revision id: 2, reading_list_id: 4, 
 created_at: "2009-01-14 21:49:56", 
 updated_at: "2009-01-14 21:49:56">]

The coolest thing about this is that conditions takes a Range object, so it's easy to look up things within a date range. It gets translated to a SQL BETWEEN clause... very handy!