Skip to content

Commit b7f9de2

Browse files
committed
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.
1 parent ad3d333 commit b7f9de2

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

activesupport/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Override `Time.at` to support the passing of Time-like values when called with a single argument.
2+
3+
*Andrew White*
4+
15
* Prevent side effects to hashes inside arrays when
26
`Hash#with_indifferent_access` is called.
37
Fixes #10526

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ def local_time(*args)
6565
def current
6666
::Time.zone ? ::Time.zone.now : ::Time.now
6767
end
68+
69+
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
70+
# instances can be used when called with a single argument
71+
def at_with_coercion(*args)
72+
if args.size == 1 && args.first.acts_like?(:time)
73+
at_without_coercion(args.first.to_i)
74+
else
75+
at_without_coercion(*args)
76+
end
77+
end
78+
alias_method :at_without_coercion, :at
79+
alias_method :at, :at_with_coercion
6880
end
6981

7082
# Seconds since midnight: Time.now.seconds_since_midnight

activesupport/test/core_ext/time_ext_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,28 @@ def test_compare_with_time_with_zone
741741
assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
742742
end
743743

744+
def test_at_with_datetime
745+
assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0))
746+
747+
# Only test this if the underlying Time.at raises a TypeError
748+
begin
749+
Time.at_without_coercion(Time.now, 0)
750+
rescue TypeError
751+
assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) }
752+
end
753+
end
754+
755+
def test_at_with_time_with_zone
756+
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']))
757+
758+
# Only test this if the underlying Time.at raises a TypeError
759+
begin
760+
Time.at_without_coercion(Time.now, 0)
761+
rescue TypeError
762+
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)) }
763+
end
764+
end
765+
744766
def test_eql?
745767
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
746768
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )

0 commit comments

Comments
 (0)