Ruby date math: Why off by a day

datetime, ruby, ruby-on-rails

Solution

Sounds like a rounding issue? `to_i` is not good for doing rounding as it flat out truncates floating point or rational numbers.

So if your expression returns 29.999999, which is basically 30, but you run `to_i` on it you end up with 29.

What you should do instead is use `round`, which does proper mathematical rounding:

(Date.today - 30.days.ago.to_date).round
=> 30

EDIT

Actually I was wrong. The reason is that the Rails `ago` method returns time in UTC time zone, not as local time. Whereas `Date.today` seems to return in local time.

So if you are (un)lucky you will get an offset of 1 day if the local time and UTC time difference happens to be crossing midnight.

The proper fix is to call `localtime` on `ago` to convert the returned time to the local time zone:

30.days.ago
=> Sat, 16 Jun 2012 03:17:44 UTC +00:00

30.days.ago.localtime
=> Sat Jun 16 06:21:47 +0300 2012

(Date.today - 30.days.ago.localtime.to_date).to_i
=> 30

Problem

I am trying to find out how many days ago a `Date` object is. ``` (Date.today - start_time).to_i ``` When I do `(Date.today - 30.days.ago.to_date).to_i` I get `29`. Thoughts?

Original source