Skip to content

Commit

Permalink
Override Time.at to work with Time-like values
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pixeltrix committed Jun 8, 2013
1 parent ad3d333 commit b7f9de2
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
4 changes: 4 additions & 0 deletions activesupport/CHANGELOG.md
@@ -1,3 +1,7 @@
* Override `Time.at` to support the passing of Time-like values when called with a single argument.

*Andrew White*

* Prevent side effects to hashes inside arrays when
`Hash#with_indifferent_access` is called.
Fixes #10526
Expand Down
12 changes: 12 additions & 0 deletions activesupport/lib/active_support/core_ext/time/calculations.rb
Expand Up @@ -65,6 +65,18 @@ def local_time(*args)
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

# Seconds since midnight: Time.now.seconds_since_midnight
Expand Down
22 changes: 22 additions & 0 deletions activesupport/test/core_ext/time_ext_test.rb
Expand Up @@ -741,6 +741,28 @@ def test_compare_with_time_with_zone
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"]) )
Expand Down

0 comments on commit b7f9de2

Please sign in to comment.