mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Adding Time and DateTime #compare_with_coercion, which layers behavior on #<=> so that any combination of Time, DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8711 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
*SVN*
|
||||
|
||||
* Adding Time and DateTime #compare_with_coercion, which layers behavior on #<=> so that any combination of Time, DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared [Geoff Buesing]
|
||||
|
||||
* TimeZone#now returns an ActiveSupport::TimeWithZone [Geoff Buesing]
|
||||
|
||||
* Time #in_current_time_zone and #change_time_zone_to_current return self when Time.zone is nil [Geoff Buesing]
|
||||
|
||||
@@ -7,6 +7,11 @@ module ActiveSupport #:nodoc:
|
||||
module Calculations
|
||||
def self.included(base) #:nodoc:
|
||||
base.extend ClassMethods
|
||||
|
||||
base.class_eval do
|
||||
alias_method :compare_without_coercion, :<=>
|
||||
alias_method :<=>, :compare_with_coercion
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
@@ -91,6 +96,13 @@ module ActiveSupport #:nodoc:
|
||||
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
|
||||
def compare_with_coercion(other)
|
||||
other = other.comparable_time if other.respond_to?(:comparable_time)
|
||||
other = other.to_datetime unless other.acts_like?(:date)
|
||||
compare_without_coercion(other)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,8 +9,12 @@ module ActiveSupport #:nodoc:
|
||||
base.class_eval do
|
||||
alias_method :plus_without_duration, :+
|
||||
alias_method :+, :plus_with_duration
|
||||
|
||||
alias_method :minus_without_duration, :-
|
||||
alias_method :-, :minus_with_duration
|
||||
|
||||
alias_method :compare_without_coercion, :<=>
|
||||
alias_method :<=>, :compare_with_coercion
|
||||
end
|
||||
end
|
||||
|
||||
@@ -218,6 +222,19 @@ module ActiveSupport #:nodoc:
|
||||
minus_without_duration(other)
|
||||
end
|
||||
end
|
||||
|
||||
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
||||
# can be chronologically compared with a Time
|
||||
def compare_with_coercion(other)
|
||||
# if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparision
|
||||
other = other.comparable_time if other.respond_to?(:comparable_time)
|
||||
if other.acts_like?(:date)
|
||||
# other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
|
||||
to_datetime.compare_without_coercion(other)
|
||||
else
|
||||
compare_without_coercion(other)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -105,7 +105,6 @@ module ActiveSupport
|
||||
|
||||
# Use the time in UTC for comparisons
|
||||
def <=>(other)
|
||||
other = other.comparable_time if other.respond_to?(:comparable_time) # to coerce time from TimeWithZone
|
||||
utc <=> other
|
||||
end
|
||||
|
||||
|
||||
@@ -253,6 +253,24 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
|
||||
assert_equal '-05:00', dt.formatted_offset
|
||||
assert_equal '-0500', dt.formatted_offset(false)
|
||||
end
|
||||
|
||||
def test_compare_with_time
|
||||
assert_equal 1, DateTime.civil(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59)
|
||||
assert_equal 0, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 1))
|
||||
end
|
||||
|
||||
def test_compare_with_datetime
|
||||
assert_equal 1, DateTime.civil(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
|
||||
assert_equal 0, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
|
||||
end
|
||||
|
||||
def test_compare_with_time_with_zone
|
||||
assert_equal 1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) )
|
||||
assert_equal 0, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) )
|
||||
assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) ))
|
||||
end
|
||||
|
||||
protected
|
||||
def with_timezone(new_tz = 'US/Eastern')
|
||||
|
||||
@@ -424,6 +424,24 @@ class TimeExtCalculationsTest < Test::Unit::TestCase
|
||||
assert_equal '-0400', Time.local(2000, 7).formatted_offset(false)
|
||||
end
|
||||
end
|
||||
|
||||
def test_compare_with_time
|
||||
assert_equal 1, Time.utc(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59, 999)
|
||||
assert_equal 0, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0, 001))
|
||||
end
|
||||
|
||||
def test_compare_with_datetime
|
||||
assert_equal 1, Time.utc(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
|
||||
assert_equal 0, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
|
||||
end
|
||||
|
||||
def test_compare_with_time_with_zone
|
||||
assert_equal 1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) )
|
||||
assert_equal 0, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) )
|
||||
assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) ))
|
||||
end
|
||||
|
||||
protected
|
||||
def with_timezone(new_tz = 'US/Eastern')
|
||||
|
||||
@@ -87,12 +87,24 @@ uses_tzinfo 'TimeWithZoneTest' do
|
||||
def test_xmlschema
|
||||
assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema
|
||||
end
|
||||
|
||||
def test_compare
|
||||
|
||||
def test_compare_with_time
|
||||
assert_equal 1, @twz <=> Time.utc(1999, 12, 31, 23, 59, 59)
|
||||
assert_equal 0, @twz <=> Time.utc(2000)
|
||||
assert_equal 0, @twz <=> Time.utc(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, @twz <=> Time.utc(2000, 1, 1, 0, 0, 1))
|
||||
end
|
||||
|
||||
def test_compare_with_datetime
|
||||
assert_equal 1, @twz <=> DateTime.civil(1999, 12, 31, 23, 59, 59)
|
||||
assert_equal 0, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 0)
|
||||
assert_equal(-1, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 1))
|
||||
end
|
||||
|
||||
def test_compare_with_time_with_zone
|
||||
assert_equal 1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) )
|
||||
assert_equal 0, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) )
|
||||
assert_equal(-1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) ))
|
||||
end
|
||||
|
||||
def test_plus
|
||||
assert_equal Time.utc(1999, 12, 31, 19, 0 ,5), (@twz + 5).time
|
||||
|
||||
Reference in New Issue
Block a user