diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index b2330f2c9d..63e2e44597 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,17 @@ +* Fix `Time#advance` to work with dates before 1001-03-07 + + Before: + + Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC + + After + + Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC + + Note that this doesn't affect `DateTime#advance` as that doesn't use a proleptic calendar. + + *Andrew White* + * In Zeitwerk mode, engines are now managed by the `main` autoloader. Engines may reference application constants, if the application is reloaded and we do not reload engines, they won't use the reloaded application code. *Xavier Noria* diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 120768dec5..f09a6271ad 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -170,8 +170,7 @@ class Time options[:hours] = options.fetch(:hours, 0) + 24 * partial_days end - d = to_date.advance(options) - d = d.gregorian if d.julian? + d = to_date.gregorian.advance(options) time_advanced_by_date = change(year: d.year, month: d.month, day: d.day) seconds_to_advance = \ options.fetch(:seconds, 0) + diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index 7078f3506d..590b81b770 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -514,6 +514,8 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal Time.local(1582, 10, 15, 15, 15, 10), Time.local(1582, 10, 14, 15, 15, 10).advance(days: 1) assert_equal Time.local(1582, 10, 5, 15, 15, 10), Time.local(1582, 10, 4, 15, 15, 10).advance(days: 1) assert_equal Time.local(1582, 10, 4, 15, 15, 10), Time.local(1582, 10, 5, 15, 15, 10).advance(days: -1) + assert_equal Time.local(999, 10, 4, 15, 15, 10), Time.local(1000, 10, 4, 15, 15, 10).advance(years: -1) + assert_equal Time.local(1000, 10, 4, 15, 15, 10), Time.local(999, 10, 4, 15, 15, 10).advance(years: 1) end def test_last_week