Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

TimeWithZone comparison fails for distinct instances of same time

#3117

Let's say I have a model "Role" with timestamps and a string name attribute. I want to do some time comparisons. Here's the expected versus actual that I see:

Expected:

r = Role.create(:name => 'a role')
initial=r.created_at
r.reload
initial==r.created_at
=> true

Actual:

r=Role.create(:name => 'a role') => # initial = r.created_at => Sun, 30 Aug 2009 09:46:14 EDT -04:00 r.reload => # r.created_at == initial => false

I've tried <=>, converting to other types (Time, DateTime), and the comparison always fails. What's going on?

Reported by Ari Epstein · August 30th, 2009 @ 03:05 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Ari Epstein
    Ari Epstein
    • Tag set to activesupport, datetime, time, timewithzone

    August 30th, 2009 @ 03:05 PM

  2. Matt Duncan
    Matt Duncan

    I was unable to reproduce this on master.

    Loading development environment (Rails 3.0.pre)
    >> r = Role.create(:name => 'a role')
    => #<Role id: 2, name: "a role", created_at: "2009-08-30 16:10:18", updated_at: "2009-08-30 16:10:18">
    >> initial = r.created_at
    => Sun, 30 Aug 2009 16:10:18 UTC +00:00
    >> r.reload
    => #<Role id: 2, name: "a role", created_at: "2009-08-30 16:10:18", updated_at: "2009-08-30 16:10:18">
    >> initial == r.created_at
    => true
    

    August 30th, 2009 @ 05:12 PM

  3. Matt Jones
    Matt Jones

    I've seen this happen in tests before - typically caused by the database having a different time resolution than the system. So even though the two times print identically, one is really (for instance) 15:45:32.012445362 and the DB loads back 15:45:32, which doesn't compare as equal.

    September 5th, 2009 @ 05:42 AM

  4. JackC
    JackC

    Just ran into this in tests myself. You can determine the usec method to see the difference. I worked around this in my tests by specifying times instead of using the current time.

    October 5th, 2009 @ 07:47 PM

  5. Geoff Buesing
    Geoff Buesing
    • State changed from new to invalid

    Matt Jones is probably right; this looks to be an issue with the database not storing usec.

    In your tests, you can try coercing to_a before comparing; usec value isn't returned in the to_a representation:

    assert_equal initial.to_a, r.created_at.to_a
    

    October 27th, 2009 @ 02:34 AM