Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #10080 (new defect)

Opened 10 months ago

Last modified 9 months ago

DateTime extension requires == operator

Reported by: lawrence Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveSupport Version: edge
Severity: normal Keywords: test datetime
Cc: tolsen

Description

Within the AR tests, when I modified the first line of test_saves_both_date_and_time in date_time_test.rb from:

  now = 200.years.ago.to_datetime

to:

  now = 20.years.ago.to_datetime

The test failed with the message:

 1) Failure:
test_saves_both_date_and_time(DateTimeTest) [test/date_time_test.rb:13]:
<Thu, 05 Nov 1987 19:09:39 +1100> expected but was
<Thu, 05 Nov 1987 19:09:39 +1100>.

After some investigation it turns out the datetime extension in active support is the culprit. It misses the == operator. Attached is a test to show the issue.

(as follow up to #10073)

Attachments

date_time_ext_test.patch (0.8 kB) - added by lawrence on 11/06/07 01:11:02.

Change History

11/06/07 01:11:02 changed by lawrence

  • attachment date_time_ext_test.patch added.

(follow-up: ↓ 2 ) 11/06/07 01:11:18 changed by lawrence

  • keywords changed from patch test datetime to test datetime.

(in reply to: ↑ 1 ) 11/06/07 04:09:13 changed by gbuesing

Replying to lawrence:

Here's the reason why two DateTimes that look the same aren't actually equal -- they have different #start values, which don't show up in the inspect:

>> 20.years.ago.to_datetime.start
=> 2299161
>> 200.years.ago.to_datetime.start
=> 0

The first example calls Time#to_datetime, and the second example calls DateTime#to_datetime, hence the different results.

ActiveSupport's Time#time_with_datetime_fallback creates DateTimes with a start value (i.e, Julian day of calendar reform) of 0, as does ActiveSupport's Time#to_datetime.

Ruby 1.8.6's private Time#to_datetime, which is made public by ActiveSupport, is overwriting ActiveSupport's own #to_datetime, and this implementation defaults to the Italian day of calendar reform -- see this plain vanilla irb session:

irb(main):001:0> require 'date'
=> true
irb(main):002:0> Time.now.to_datetime
NoMethodError: private method `to_datetime' called for Mon Nov 05 21:31:40 -0600 2007:Time
        from (irb):2
irb(main):003:0> Time.now.__send__(:to_datetime)
=> #<DateTime: 212061079941799849/86400000000,-1/4,2299161>
irb(main):004:0> Time.now.__send__(:to_datetime).start
=> 2299161

12/06/07 17:00:12 changed by tolsen

  • cc set to tolsen.

test_saves_both_date_and_time fails for me the same way, but without even changing 200.years to 20.years. I am using sqlite3 and ruby 1.8.6.111

12/07/07 03:00:53 changed by gbuesing

(In [8326]) Anchor DateTimeTest to fixed DateTime instead of a variable value based on Time.now#advance#to_datetime. Works around issue on 64-bit platforms with Ruby's Time#to_datetime respecting fractional seconds, and database adapters not respecting them for DateTimes, throwing off before-and-after-save equality test. References #10080, #10073