Skip to content

Commit e0a9ef1

Browse files
authored
Merge pull request rails#52370 from jhawthorn/time_addition_deprecation
Combined time addition deprecation
2 parents b669f15 + 3df6768 commit e0a9ef1

File tree

5 files changed

+45
-3
lines changed

5 files changed

+45
-3
lines changed

activesupport/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
* Deprecate addition and since between two `Time` and `ActiveSupport::TimeWithZone`.
2+
3+
Previously adding time instances together such as `10.days.ago + 10.days.ago` or `10.days.ago.since(10.days.ago)` produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.
4+
5+
*Nick Schwaderer*
6+
17
* Support rfc2822 format for Time#to_fs & Date#to_fs.
28

39
*Akshay Birajdar*

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,13 @@ def ago(seconds)
224224
# Returns a new Time representing the time a number of seconds since the instance time
225225
def since(seconds)
226226
self + seconds
227-
rescue
228-
to_datetime.since(seconds)
227+
rescue TypeError
228+
result = to_datetime.since(seconds)
229+
ActiveSupport.deprecator.warn(
230+
"Passing an instance of #{seconds.class} to #{self.class}#since is deprecated. This behavior will raise " \
231+
"a `TypeError` in Rails 8.1."
232+
)
233+
result
229234
end
230235
alias :in :since
231236

activesupport/lib/active_support/time_with_zone.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,16 @@ def +(other)
300300
if duration_of_variable_length?(other)
301301
method_missing(:+, other)
302302
else
303-
result = utc + other
303+
begin
304+
result = utc + other
305+
rescue TypeError
306+
result = utc.to_datetime.since(other)
307+
ActiveSupport.deprecator.warn(
308+
"Adding an instance of #{other.class} to an instance of #{self.class} is deprecated. This behavior will raise " \
309+
"a `TypeError` in Rails 8.1."
310+
)
311+
result.in_time_zone(time_zone)
312+
end
304313
result.in_time_zone(time_zone)
305314
end
306315
end

activesupport/test/core_ext/time_ext_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,12 @@ def test_daylight_savings_time_crossings_backward_end_1day
282282
end
283283
end
284284

285+
def test_since_with_instance_of_time_deprecated
286+
assert_deprecated(ActiveSupport.deprecator) do
287+
Time.now.since(Time.now)
288+
end
289+
end
290+
285291
def test_since
286292
assert_equal Time.local(2005, 2, 22, 10, 10, 11), Time.local(2005, 2, 22, 10, 10, 10).since(1)
287293
assert_equal Time.local(2005, 2, 22, 11, 10, 10), Time.local(2005, 2, 22, 10, 10, 10).since(3600)

activesupport/test/core_ext/time_with_zone_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,22 @@ def test_no_limit_on_times
400400
assert_equal [0, 0, 19, 31, 12, -8001], (twz - 10_000.years).to_a[0, 6]
401401
end
402402

403+
def test_plus_two_time_instances_raises_deprecation_warning
404+
twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), @time_zone)
405+
assert_deprecated(ActiveSupport.deprecator) do
406+
twz + 10.days.ago
407+
end
408+
end
409+
410+
def test_plus_with_invalid_argument
411+
twz = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), @time_zone)
412+
assert_not_deprecated(ActiveSupport.deprecator) do
413+
assert_raises TypeError do
414+
twz + Object.new
415+
end
416+
end
417+
end
418+
403419
def test_plus_with_duration
404420
assert_equal Time.utc(2000, 1, 5, 19, 0, 0), (@twz + 5.days).time
405421
end

0 commit comments

Comments
 (0)