Skip to content

Commit a93ee92

Browse files
committed
Merge pull request rails#3725 from marcandre/twz_eql
Fix inconsistencies with Time{WithZone}#{hash,eql?}
2 parents 9b7be78 + a491207 commit a93ee92

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

activesupport/lib/active_support/core_ext/time/calculations.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,14 @@ def compare_with_coercion(other)
312312
end
313313
alias_method :compare_without_coercion, :<=>
314314
alias_method :<=>, :compare_with_coercion
315+
316+
# Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
317+
# can be eql? to an equivalent Time
318+
def eql_with_coercion(other)
319+
# if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
320+
other = other.comparable_time if other.respond_to?(:comparable_time)
321+
eql_without_coercion(other)
322+
end
323+
alias_method :eql_without_coercion, :eql?
324+
alias_method :eql?, :eql_with_coercion
315325
end

activesupport/lib/active_support/time_with_zone.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,11 @@ def future?
203203
end
204204

205205
def eql?(other)
206-
utc == other
206+
utc.eql?(other)
207+
end
208+
209+
def hash
210+
utc.hash
207211
end
208212

209213
def +(other)
@@ -277,7 +281,6 @@ def to_f
277281
def to_i
278282
utc.to_i
279283
end
280-
alias_method :hash, :to_i
281284
alias_method :tv_sec, :to_i
282285

283286
# A TimeWithZone acts like a Time, so just return +self+.

activesupport/test/core_ext/time_ext_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,12 @@ def test_compare_with_time_with_zone
744744
assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
745745
end
746746

747+
def test_eql?
748+
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
749+
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
750+
assert_equal false,Time.utc(2000, 1, 1, 0, 0, 1).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
751+
end
752+
747753
def test_minus_with_time_with_zone
748754
assert_equal 86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
749755
end

activesupport/test/core_ext/time_with_zone_test.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,15 @@ def future_with_time_current_as_time_with_zone
200200
end
201201

202202
def test_eql?
203-
assert @twz.eql?(Time.utc(2000))
204-
assert @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
203+
assert_equal true, @twz.eql?(Time.utc(2000))
204+
assert_equal true, @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
205+
assert_equal false, @twz.eql?( Time.utc(2000, 1, 1, 0, 0, 1) )
206+
assert_equal false, @twz.eql?( DateTime.civil(1999, 12, 31, 23, 59, 59) )
207+
end
208+
209+
def test_hash
210+
assert_equal Time.utc(2000).hash, @twz.hash
211+
assert_equal Time.utc(2000).hash, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]).hash
205212
end
206213

207214
def test_plus_with_integer

0 commit comments

Comments
 (0)