Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow DateTime comparison to Infinity/-Infinity. #3457

Closed
wants to merge 1 commit into from

7 participants

@joevandyk

A continuation of the fixes in #544 -- @tenderlove let ActiveRecord support Infinite timestamps, but you can't compare them to other DateTime values. This commit fixes that.

@monde

-1

@joevandyk

damn it mike

...lib/active_support/core_ext/date_time/calculations.rb
@@ -127,6 +127,10 @@ class DateTime
# Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
def <=>(other)
- super other.to_datetime
+ if other.respond_to?(:infinite?) and other.infinite? != 0
+ -other.infinite?
@dbenhur
dbenhur added a note

if self is also an infinite you should check for equality and relative signage with other

DateTime can't be an infinite, I believe. So self could never be an infinite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
activesupport/test/core_ext/date_time_ext_test.rb
@@ -375,6 +375,13 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
end
+ def test_compare_with_infinite
+ big_bang = -(1.0/0)
+ cold_death = (1.0/0)
+ assert_equal 1, DateTime.civil(2000) <=> big_bang
+ assert_equal -1, DateTime.civil(2000) <=> cold_death
+ end
@dbenhur
dbenhur added a note

Here's the missing edge cases (see http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html)

assert_equal 1, cold_death <=> big_bang
assert_equal -1, big_bang <=> cold_death
assert_equal 0, big_bang <=> big_bang
assert_equal 0, cold_death <=> cold_death

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@dbenhur

maybe mike meant -∞ :). I added a comment and test cases to your pull request to cover equality and signage comparisons if both operands are a flavor of infinite.

@joevandyk

Thanks! I'll make those changes soon.

@joevandyk

I added the missing test cases.

@isaacsanders

Is this still an issue?

@joevandyk

Yes.

@tenderlove tenderlove was assigned
@steveklabnik
Collaborator

This will need a big rebase if it's ever to be included.

@steveklabnik
Collaborator

@joevandyk ping! any interest in keeping this current?

@joevandyk

this isn't in there yet? :) i'll look at it.

@rafaelfranca

Fixed by #7350

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 27, 2012
  1. @joevandyk
This page is out of date. Refresh to see the latest.
View
9 activesupport/lib/active_support/core_ext/date_time/calculations.rb
@@ -125,8 +125,13 @@ def utc_offset
(offset * 86400).to_i
end
- # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
+ # Layers additional behavior on DateTime#<=> so that Time, ActiveSupport::TimeWithZone, and
+ # Infinity instances can be compared with a DateTime.
def <=>(other)
- super other.to_datetime
+ if other.respond_to?(:infinite?)
+ -other.infinite?
+ else
+ super other.to_datetime
+ end
end
end
View
14 activesupport/test/core_ext/date_time_ext_test.rb
@@ -99,7 +99,7 @@ def test_weeks_ago
assert_equal DateTime.civil(2005,5,1,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(5)
assert_equal DateTime.civil(2005,4,24,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(6)
assert_equal DateTime.civil(2005,2,27,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(14)
- assert_equal DateTime.civil(2004,12,25,10), DateTime.civil(2005,1,1,10,0,0).weeks_ago(1)
+ assert_equal DateTime.civil(2004,12,25,10), DateTime.civil(2005,1,1,10,0,0).weeks_ago(1)
end
def test_months_ago
@@ -375,6 +375,18 @@ def test_compare_with_time_with_zone
assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
end
+ # http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Infinity-and-NaN.html
+ def test_compare_with_infinite
+ big_bang = -(1.0/0)
+ cold_death = (1.0/0)
+ assert_equal 1, DateTime.civil(2000) <=> big_bang
+ assert_equal -1, DateTime.civil(2000) <=> cold_death
+ assert_equal 1, cold_death <=> big_bang
+ assert_equal -1, big_bang <=> cold_death
+ assert_equal 0, big_bang <=> big_bang
+ assert_equal 0, cold_death <=> cold_death
+ end
+
def test_to_f
assert_equal 946684800.0, DateTime.civil(2000).to_f
assert_equal 946684800.0, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_f
Something went wrong with that request. Please try again.