Peter Marklund

Peter Marklund's Home

Fri August 31, 2007
Programming

Rails Gotcha: The Contract of 1.month.ago

At first glance the contract of the beautiful 1.month.ago construct in Rails is maybe obvious. However, what should it return if the current time is the 31st of March? Remember that february only has 28 days. Well, according to Rails 1.2.3 the answer is 1st of March, but according to Edge Rails the answer is (and I agree with Edge Rails here) 28:th of February.

The 1.month.ago issue is something that bit me and that you should be aware of. So with Rails 1.2.3, if you want to be sure to get the beginning of the previous month, you need to say 1.month.until(Time.now.beginning_of_month). At least that's the workaround I'm using now.

Comments

Jack Nutting said over 6 years ago:

I stumbled across the exact same problem yesterday. The solution that I found is to use months_ago or months_since, like this:

Time.now.beginning_of_month.months_ago(1)

This moves away from the railsian integer-overloading concept a bit, which is either a welcome move or an unfortunate paradigm-break, depending on your point of view ;)

--------------------------------------------------------------------------------

Peter Marklund said over 6 years ago:

Thanks Jack, that looks like a better construct. Personally, I've gotten used to the integer overloading, although I remember it was odd to me in my early Rails days. I think that logically, and from an OO-design point of view, it makes more sense to use a time object as a starting point rather than an integer.

--------------------------------------------------------------------------------