Hire Us

Time comparison in Ruby

I believe every ruby developer has faced time comparison issue at least once and tests are one of the possible areas where it may happen. RSpec message like this may confuse:
confirmed_at should have been changed to Mon, 24 Mar 2014 09:47:22 UTC, 
but is now Mon, 24 Mar 2014 09:47:22 UTC
What’s wrong?


Let’s create two Time objects:
> t1, t2 = Time.now, Time.now
=> [2014-03-27 23:19:18 UTC, 2014-03-27 23:19:18 UTC]
At the first glance, they are equal. But it’s not true:
> t1 == t2
=> false
The issue occurs because ruby Time makes comparison with fractions of seconds. We may use to_f method to see the difference between t1 and t2:
> t1.to_f
=> 1395955158.547284
> t2.to_f
=> 1395955158.547298
or to_r method to get rational numbers:
> t1.to_r
=> (348988789636821/250000)
> t2.to_r
=> (697977579273649/500000)


If you don’t care about milliseconds, you may compare timestamps using to_i method:
> t1.to_i == t2.to_i
=> true
or make a new Time object from timestamps to have better RSpec failure messages:
> Time.at(t1.to_i) == Time.at(t2.to_i)
=> true
But even better to use fixed times in our tests.