From f42e0fd3f4d3e2f4b806b001b6ed88c8da8cd833 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sat, 8 Jun 2013 08:22:29 +0100 Subject: Override Time.at to work with Time-like values Time.at allows passing a single Time argument which is then converted to an integer. The conversion code since 1.9.3r429 explicitly checks for an instance of Time so we need to override it to allow DateTime and ActiveSupport::TimeWithZone values. --- activesupport/CHANGELOG.md | 4 ++++ .../active_support/core_ext/time/calculations.rb | 12 ++++++++++++ activesupport/test/core_ext/time_ext_test.rb | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 7f2acb2f65..d612c644af 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,5 +1,9 @@ ## unreleased ## +* Override `Time.at` to support the passing of Time-like values when called with a single argument. + + *Andrew White* + * Revert the changes on unicode character encoding from `ActiveSupport::JSON.encode`. This was causing a regression where the resulting string is always returning UTF-8. Also it changes the behavior of this method on a stable release. diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 9146d82bd8..7524063efb 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -45,6 +45,18 @@ class Time def current ::Time.zone ? ::Time.zone.now : ::Time.now end + + # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime + # instances can be used when called with a single argument + def at_with_coercion(*args) + if args.size == 1 && args.first.acts_like?(:time) + at_without_coercion(args.first.to_i) + else + at_without_coercion(*args) + end + end + alias_method :at_without_coercion, :at + alias_method :at, :at_with_coercion end # Tells whether the Time object's time lies in the past diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index 0d680832ef..a22e161279 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -774,6 +774,28 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] )) end + def test_at_with_datetime + assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0)) + + # Only test this if the underlying Time.at raises a TypeError + begin + Time.at_without_coercion(Time.now, 0) + rescue TypeError + assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) } + end + end + + def test_at_with_time_with_zone + assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC'])) + + # Only test this if the underlying Time.at raises a TypeError + begin + Time.at_without_coercion(Time.now, 0) + rescue TypeError + assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']), 0)) } + end + end + def test_eql? assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) ) assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) -- cgit v1.2.3