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

Changeset 8711

Show
Ignore:
Timestamp:
01/23/08 22:22:36 (9 months ago)
Author:
gbuesing
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activesupport/CHANGELOG

    r8710 r8711  
    11*SVN* 
     2 
     3* 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] 
    24 
    35* TimeZone#now returns an ActiveSupport::TimeWithZone [Geoff Buesing] 
  • trunk/activesupport/lib/active_support/core_ext/date_time/calculations.rb

    r8649 r8711  
    88        def self.included(base) #:nodoc: 
    99          base.extend ClassMethods 
     10           
     11          base.class_eval do 
     12            alias_method :compare_without_coercion, :<=> 
     13            alias_method :<=>, :compare_with_coercion 
     14          end 
    1015        end 
    1116 
     
    9297          (offset * 86400).to_i 
    9398        end 
     99         
     100        # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime 
     101        def compare_with_coercion(other) 
     102          other = other.comparable_time if other.respond_to?(:comparable_time) 
     103          other = other.to_datetime unless other.acts_like?(:date) 
     104          compare_without_coercion(other) 
     105        end 
    94106      end 
    95107    end 
  • trunk/activesupport/lib/active_support/core_ext/time/calculations.rb

    r8199 r8711  
    1010            alias_method :plus_without_duration, :+ 
    1111            alias_method :+, :plus_with_duration 
     12             
    1213            alias_method :minus_without_duration, :- 
    1314            alias_method :-, :minus_with_duration 
     15             
     16            alias_method :compare_without_coercion, :<=> 
     17            alias_method :<=>, :compare_with_coercion 
    1418          end 
    1519        end 
     
    219223          end 
    220224        end 
     225         
     226        # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances 
     227        # can be chronologically compared with a Time 
     228        def compare_with_coercion(other) 
     229          # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparision 
     230          other = other.comparable_time if other.respond_to?(:comparable_time) 
     231          if other.acts_like?(:date) 
     232            # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=> 
     233            to_datetime.compare_without_coercion(other) 
     234          else 
     235            compare_without_coercion(other) 
     236          end 
     237        end 
    221238      end 
    222239    end 
  • trunk/activesupport/lib/active_support/time_with_zone.rb

    r8696 r8711  
    106106    # Use the time in UTC for comparisons 
    107107    def <=>(other) 
    108       other = other.comparable_time if other.respond_to?(:comparable_time) # to coerce time from TimeWithZone 
    109108      utc <=> other 
    110109    end 
  • trunk/activesupport/test/core_ext/date_time_ext_test.rb

    r8698 r8711  
    254254    assert_equal '-0500', dt.formatted_offset(false) 
    255255  end 
     256   
     257  def test_compare_with_time 
     258    assert_equal  1, DateTime.civil(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59) 
     259    assert_equal  0, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0) 
     260    assert_equal(-1, DateTime.civil(2000) <=> Time.utc(2000, 1, 1, 0, 0, 1)) 
     261  end 
     262   
     263  def test_compare_with_datetime 
     264    assert_equal  1, DateTime.civil(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59) 
     265    assert_equal  0, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0) 
     266    assert_equal(-1, DateTime.civil(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1)) 
     267  end 
     268   
     269  def test_compare_with_time_with_zone 
     270    assert_equal  1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) ) 
     271    assert_equal  0, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) ) 
     272    assert_equal(-1, DateTime.civil(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) )) 
     273  end 
    256274 
    257275  protected 
  • trunk/activesupport/test/core_ext/time_ext_test.rb

    r8698 r8711  
    425425    end 
    426426  end 
     427   
     428  def test_compare_with_time 
     429    assert_equal  1, Time.utc(2000) <=> Time.utc(1999, 12, 31, 23, 59, 59, 999) 
     430    assert_equal  0, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0) 
     431    assert_equal(-1, Time.utc(2000) <=> Time.utc(2000, 1, 1, 0, 0, 0, 001)) 
     432  end 
     433   
     434  def test_compare_with_datetime 
     435    assert_equal  1, Time.utc(2000) <=> DateTime.civil(1999, 12, 31, 23, 59, 59) 
     436    assert_equal  0, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 0) 
     437    assert_equal(-1, Time.utc(2000) <=> DateTime.civil(2000, 1, 1, 0, 0, 1)) 
     438  end 
     439   
     440  def test_compare_with_time_with_zone 
     441    assert_equal  1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) ) 
     442    assert_equal  0, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) ) 
     443    assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) )) 
     444  end 
    427445 
    428446  protected 
  • trunk/activesupport/test/core_ext/time_with_zone_test.rb

    r8708 r8711  
    8888      assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema 
    8989    end 
    90        
    91     def test_compare 
     90     
     91    def test_compare_with_time 
    9292      assert_equal  1, @twz <=> Time.utc(1999, 12, 31, 23, 59, 59) 
    93       assert_equal  0, @twz <=> Time.utc(2000
     93      assert_equal  0, @twz <=> Time.utc(2000, 1, 1, 0, 0, 0
    9494      assert_equal(-1, @twz <=> Time.utc(2000, 1, 1, 0, 0, 1)) 
     95    end 
     96 
     97    def test_compare_with_datetime 
     98      assert_equal  1, @twz <=> DateTime.civil(1999, 12, 31, 23, 59, 59) 
     99      assert_equal  0, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 0) 
     100      assert_equal(-1, @twz <=> DateTime.civil(2000, 1, 1, 0, 0, 1)) 
     101    end 
     102 
     103    def test_compare_with_time_with_zone 
     104      assert_equal  1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(1999, 12, 31, 23, 59, 59) ) 
     105      assert_equal  0, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0) ) 
     106      assert_equal(-1, @twz <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1) )) 
    95107    end 
    96108