Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby date math: Why off by a day

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?

like image 787
Dmitriy Likhten Avatar asked Feb 19 '23 20:02

Dmitriy Likhten


1 Answers

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
like image 66
Casper Avatar answered Mar 02 '23 16:03

Casper