Thursday, 9 April 2009

Time Comparison in Ruby, especially on Rails

I had a bizarre failure in some test cases. The test case looked like this:
marker = Time.now
t.create(args)
assert t.created_at.between?(marker, Time.now)
In other words, take the time, create an object, and make sure it was created between the first time and now. Obviously true, but my test was failing.

The reason: Rails keeps the create time to the second, but Ruby keeps time to fractions of a second (depending on the resolution of your hardware clock). Both would have the same time (to the second) but the marker would have some microseconds more than t.created_at, so the assertion would fail.

The Ruby documentation actually warns you about this, but in way that's cryptic enough that it might not be obvious why your simple test case is failing in such a bizarre way.

The solution? Mine was make the time an integer and convert it back to a time using Time.at:
marker = Time.at(Time.now.to_i)
t.create(args)
assert t.created_at.between?(marker, Time.now)
This doesn't really merit a blog post, except that I Googled for solutions to the problem and didn't find much.

1 comment:

Anonymous said...

Nice post and this fill someone in on helped me alot in my college assignement. Thanks you on your information.