# Timecop time and database time

June 8, 2014

Timecop is a great addition to your testing toolbox, but if you’ve ever tried to use Timecop to interact with a database, and then got the most mysterious of existential errors:

expected: Sun, 08 Jun 2014 19:18:22 UTC +00:00
got: Sun, 08 Jun 2014 19:18:22 UTC +00:00


The trouble comes from the fact that Timecop is freezing time at the resolution of the native Time class, which on my Mac OS X machine is microseconds (aka “usec”), but the database, in this case MySQL only records time to the second. RSpec is trying to be helpful with its matchers by calling <code>#to_s, but that hides the significant, sub-second difference.

Here’s a quick little monkey patch that I added to my spec support:

class Timecop
def self.database_compatible_time(now = Time.zone.now)
now.change(usec: 0)
end
end


This uses a Rails helper to reset the microsecond portion of the time object. So, instead of

now = Time.zone.now

Timecop.freeze(now) do
...
end


I do this:

now = Timecop.database_compatible_time

Timecop.freeze(now) do
...
end
`

And no more head scratching. It’s sort of database specific, so your mileage may vary.

Timecop time and database time - June 8, 2014 - Ken Mayer