diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb
index 2d6aeba85e..c7dab09b29 100644
--- a/activesupport/lib/active_support.rb
+++ b/activesupport/lib/active_support.rb
@@ -111,15 +111,17 @@ def self.cache_format_version=(value)
end
def self.to_time_preserves_timezone
- ActiveSupport.deprecator.warn(
- "`config.active_support.to_time_preserves_timezone` has been deprecated and will be removed in Rails 7.3."
- )
+ DateAndTime::Compatibility.preserve_timezone
end
def self.to_time_preserves_timezone=(value)
- ActiveSupport.deprecator.warn(
- "`config.active_support.to_time_preserves_timezone` has been deprecated and will be removed in Rails 7.3."
- )
+ unless value
+ ActiveSupport.deprecator.warn(
+ "Support for the pre-Ruby 2.4 behavior of to_time has been deprecated and will be removed in Rails 7.2."
+ )
+ end
+
+ DateAndTime::Compatibility.preserve_timezone = value
end
def self.utc_to_local_returns_utc_offset_times
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb b/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb
index 0a55451dce..bc13cf96f4 100644
--- a/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb
+++ b/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb
@@ -4,6 +4,15 @@
module DateAndTime
module Compatibility
+ # If true, +to_time+ preserves the timezone offset of receiver.
+ #
+ # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
+ # converting to the local system time, to preserving the offset
+ # of the receiver. For backwards compatibility we're overriding
+ # this behavior, but new apps will have an initializer that sets
+ # this to true, because the new behavior is preferred.
+ mattr_accessor :preserve_timezone, instance_writer: false, default: false
+
# Change the output of ActiveSupport::TimeZone.utc_to_local.
#
# When +true+, it returns local times with a UTC offset, with +false+ local
@@ -18,17 +27,5 @@ module Compatibility
# # With `utc_to_local_returns_utc_offset_times = true`, local time is returned with UTC offset:
# zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 -0500
mattr_accessor :utc_to_local_returns_utc_offset_times, instance_writer: false, default: false
-
- def self.preserve_timezone
- ActiveSupport.deprecator.warn(
- "`DateAndTime::Compatibility.preserve_timezone` has been deprecated and will be removed in Rails 7.3."
- )
- end
-
- def self.preserve_timezone=(value)
- ActiveSupport.deprecator.warn(
- "`DateAndTime::Compatibility.preserve_timezone=` has been deprecated and will be removed in Rails 7.3."
- )
- end
end
end
diff --git a/activesupport/lib/active_support/core_ext/date_time/compatibility.rb b/activesupport/lib/active_support/core_ext/date_time/compatibility.rb
index 3b8d82b794..7600a067cc 100644
--- a/activesupport/lib/active_support/core_ext/date_time/compatibility.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/compatibility.rb
@@ -8,9 +8,11 @@ class DateTime
silence_redefinition_of_method :to_time
- # Return an instance of +Time+ with the same UTC offset
- # as +self+.
+ # Either return an instance of +Time+ with the same UTC offset
+ # as +self+ or an instance of +Time+ representing the same time
+ # in the local system timezone depending on the setting of
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
def to_time
- getlocal(utc_offset)
+ preserve_timezone ? getlocal(utc_offset) : getlocal
end
end
diff --git a/activesupport/lib/active_support/core_ext/time/compatibility.rb b/activesupport/lib/active_support/core_ext/time/compatibility.rb
index 88c2e1c829..495e4f307b 100644
--- a/activesupport/lib/active_support/core_ext/time/compatibility.rb
+++ b/activesupport/lib/active_support/core_ext/time/compatibility.rb
@@ -8,8 +8,9 @@ class Time
silence_redefinition_of_method :to_time
- # Returns +self+.
+ # Either return +self+ or the time in the local system timezone depending
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
def to_time
- self
+ preserve_timezone ? self : getlocal
end
end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 7d07abe2b2..f9b020ef4f 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -479,10 +479,15 @@ def to_datetime
@to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
end
- # Returns an instance of +Time+ with the same UTC offset
- # as +self+.
+ # Returns an instance of +Time+, either with the same UTC offset
+ # as +self+ or in the local system timezone depending on the setting
+ # of +ActiveSupport.to_time_preserves_timezone+.
def to_time
- @to_time_with_instance_offset ||= getlocal(utc_offset)
+ if preserve_timezone
+ @to_time_with_instance_offset ||= getlocal(utc_offset)
+ else
+ @to_time_with_system_offset ||= getlocal
+ end
end
# So that +self+ acts_like?(:time).
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index 2cd06d45d1..d5de723cfb 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -24,6 +24,11 @@
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport.deprecator.debug = true
+# Default to Ruby 2.4+ to_time behavior but allow running tests with old behavior
+ActiveSupport.deprecator.silence do
+ ActiveSupport.to_time_preserves_timezone = ENV.fetch("PRESERVE_TIMEZONES", "1") == "1"
+end
+
ActiveSupport::Cache.format_version = 7.1
# Disable available locale checks to avoid warnings running the test suite.
diff --git a/activesupport/test/core_ext/date_and_time_compatibility_test.rb b/activesupport/test/core_ext/date_and_time_compatibility_test.rb
index 639d7ec273..1b3ada7ca4 100644
--- a/activesupport/test/core_ext/date_and_time_compatibility_test.rb
+++ b/activesupport/test/core_ext/date_and_time_compatibility_test.rb
@@ -16,133 +16,280 @@ def setup
end
def test_time_to_time_preserves_timezone
- with_env_tz "US/Eastern" do
- source = Time.new(2016, 4, 23, 15, 11, 12, 3600)
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = Time.new(2016, 4, 23, 15, 11, 12, 3600)
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_equal source.object_id, time.object_id
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_equal source.object_id, time.object_id
+ end
+ end
+ end
+
+ def test_time_to_time_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = Time.new(2016, 4, 23, 15, 11, 12, 3600)
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_equal source.object_id, time.object_id
+ end
end
end
def test_time_to_time_frozen_preserves_timezone
- with_env_tz "US/Eastern" do
- source = Time.new(2016, 4, 23, 15, 11, 12, 3600).freeze
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = Time.new(2016, 4, 23, 15, 11, 12, 3600).freeze
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_equal source.object_id, time.object_id
- assert_predicate time, :frozen?
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_equal source.object_id, time.object_id
+ assert_predicate time, :frozen?
+ end
+ end
+ end
+
+ def test_time_to_time_frozen_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = Time.new(2016, 4, 23, 15, 11, 12, 3600).freeze
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_equal source.object_id, time.object_id
+ assert_not_predicate time, :frozen?
+ end
end
end
def test_datetime_to_time_preserves_timezone
- with_env_tz "US/Eastern" do
- source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24))
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24))
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ end
+ end
+ end
+
+ def test_datetime_to_time_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24))
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ end
end
end
def test_datetime_to_time_frozen_preserves_timezone
- with_env_tz "US/Eastern" do
- source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24)).freeze
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24)).freeze
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_not_predicate time, :frozen?
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
+ end
+ end
+
+ def test_datetime_to_time_frozen_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = DateTime.new(2016, 4, 23, 15, 11, 12, Rational(1, 24)).freeze
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
end
end
def test_twz_to_time_preserves_timezone
- with_env_tz "US/Eastern" do
- source = ActiveSupport::TimeWithZone.new(@utc_time, @zone)
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = ActiveSupport::TimeWithZone.new(@utc_time, @zone)
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_instance_of Time, time.getutc
- assert_equal @utc_offset, time.utc_offset
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
- source = ActiveSupport::TimeWithZone.new(@date_time, @zone)
- time = source.to_time
+ source = ActiveSupport::TimeWithZone.new(@date_time, @zone)
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @date_time, time.getutc
- assert_instance_of Time, time.getutc
- assert_equal @utc_offset, time.utc_offset
+ assert_instance_of Time, time
+ assert_equal @date_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ end
+ end
+ end
+
+ def test_twz_to_time_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = ActiveSupport::TimeWithZone.new(@utc_time, @zone)
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+
+ source = ActiveSupport::TimeWithZone.new(@date_time, @zone)
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @date_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ end
end
end
def test_twz_to_time_frozen_preserves_timezone
- with_env_tz "US/Eastern" do
- source = ActiveSupport::TimeWithZone.new(@utc_time, @zone).freeze
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = ActiveSupport::TimeWithZone.new(@utc_time, @zone).freeze
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_instance_of Time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_not_predicate time, :frozen?
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
- source = ActiveSupport::TimeWithZone.new(@date_time, @zone).freeze
- time = source.to_time
+ source = ActiveSupport::TimeWithZone.new(@date_time, @zone).freeze
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @date_time, time.getutc
- assert_instance_of Time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_not_predicate time, :frozen?
+ assert_instance_of Time, time
+ assert_equal @date_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
+ end
+ end
+
+ def test_twz_to_time_frozen_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = ActiveSupport::TimeWithZone.new(@utc_time, @zone).freeze
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+
+ source = ActiveSupport::TimeWithZone.new(@date_time, @zone).freeze
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @date_time, time.getutc
+ assert_instance_of Time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
end
end
def test_string_to_time_preserves_timezone
- with_env_tz "US/Eastern" do
- source = "2016-04-23T15:11:12+01:00"
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = "2016-04-23T15:11:12+01:00"
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ end
+ end
+ end
+
+ def test_string_to_time_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = "2016-04-23T15:11:12+01:00"
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ end
end
end
def test_string_to_time_frozen_preserves_timezone
- with_env_tz "US/Eastern" do
- source = "2016-04-23T15:11:12+01:00"
- time = source.to_time
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ source = "2016-04-23T15:11:12+01:00"
+ time = source.to_time
- assert_instance_of Time, time
- assert_equal @utc_time, time.getutc
- assert_equal @utc_offset, time.utc_offset
- assert_not_predicate time, :frozen?
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @utc_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
+ end
+ end
+
+ def test_string_to_time_frozen_does_not_preserve_time_zone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ source = "2016-04-23T15:11:12+01:00"
+ time = source.to_time
+
+ assert_instance_of Time, time
+ assert_equal @utc_time, time.getutc
+ assert_equal @system_offset, time.utc_offset
+ assert_not_predicate time, :frozen?
+ end
end
end
def test_to_time_preserves_timezone_is_deprecated
- assert_deprecated(ActiveSupport.deprecator) do
+ current_preserve_tz = ActiveSupport.to_time_preserves_timezone
+
+ assert_not_deprecated(ActiveSupport.deprecator) do
ActiveSupport.to_time_preserves_timezone
end
- assert_deprecated(ActiveSupport.deprecator) do
- DateAndTime::Compatibility.preserve_timezone
- end
-
- assert_deprecated(ActiveSupport.deprecator) do
+ assert_not_deprecated(ActiveSupport.deprecator) do
ActiveSupport.to_time_preserves_timezone = true
end
assert_deprecated(ActiveSupport.deprecator) do
- DateAndTime::Compatibility.preserve_timezone = false
+ ActiveSupport.to_time_preserves_timezone = false
+ end
+ ensure
+ ActiveSupport.deprecator.silence do
+ ActiveSupport.to_time_preserves_timezone = current_preserve_tz
end
end
end
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index ecdc278732..39efaa4667 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -77,8 +77,13 @@ def test_to_time
with_env_tz "US/Eastern" do
assert_instance_of Time, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time
- assert_equal Time.local(2005, 2, 21, 5, 11, 12).getlocal(0), DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time
- assert_equal Time.local(2005, 2, 21, 5, 11, 12).getlocal(0).utc_offset, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time.utc_offset
+ if ActiveSupport.to_time_preserves_timezone
+ assert_equal Time.local(2005, 2, 21, 5, 11, 12).getlocal(0), DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time
+ assert_equal Time.local(2005, 2, 21, 5, 11, 12).getlocal(0).utc_offset, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time.utc_offset
+ else
+ assert_equal Time.local(2005, 2, 21, 5, 11, 12), DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time
+ assert_equal Time.local(2005, 2, 21, 5, 11, 12).utc_offset, DateTime.new(2005, 2, 21, 10, 11, 12, 0).to_time.utc_offset
+ end
end
end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 4e2fc7f4e8..9fbda588b7 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -610,10 +610,17 @@ def test_timestamp_string_to_time
def test_string_to_time_utc_offset
with_env_tz "US/Eastern" do
- assert_equal 0, "2005-02-27 23:50".to_time(:utc).utc_offset
- assert_equal(-18000, "2005-02-27 23:50".to_time.utc_offset)
- assert_equal 0, "2005-02-27 22:50 -0100".to_time(:utc).utc_offset
- assert_equal(-3600, "2005-02-27 22:50 -0100".to_time.utc_offset)
+ if ActiveSupport.to_time_preserves_timezone
+ assert_equal 0, "2005-02-27 23:50".to_time(:utc).utc_offset
+ assert_equal(-18000, "2005-02-27 23:50".to_time.utc_offset)
+ assert_equal 0, "2005-02-27 22:50 -0100".to_time(:utc).utc_offset
+ assert_equal(-3600, "2005-02-27 22:50 -0100".to_time.utc_offset)
+ else
+ assert_equal 0, "2005-02-27 23:50".to_time(:utc).utc_offset
+ assert_equal(-18000, "2005-02-27 23:50".to_time.utc_offset)
+ assert_equal 0, "2005-02-27 22:50 -0100".to_time(:utc).utc_offset
+ assert_equal(-18000, "2005-02-27 22:50 -0100".to_time.utc_offset)
+ end
end
end
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index f20091b98d..19fc500878 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -517,14 +517,29 @@ def test_time_at
assert_equal time, Time.at(time)
end
- def test_to_time
- with_env_tz "US/Eastern" do
- time = @twz.to_time
+ def test_to_time_with_preserve_timezone
+ with_preserve_timezone(true) do
+ with_env_tz "US/Eastern" do
+ time = @twz.to_time
- assert_equal Time, time.class
- assert_equal time.object_id, @twz.to_time.object_id
- assert_equal Time.local(1999, 12, 31, 19), time
- assert_equal Time.local(1999, 12, 31, 19).utc_offset, time.utc_offset
+ assert_equal Time, time.class
+ assert_equal time.object_id, @twz.to_time.object_id
+ assert_equal Time.local(1999, 12, 31, 19), time
+ assert_equal Time.local(1999, 12, 31, 19).utc_offset, time.utc_offset
+ end
+ end
+ end
+
+ def test_to_time_without_preserve_timezone
+ with_preserve_timezone(false) do
+ with_env_tz "US/Eastern" do
+ time = @twz.to_time
+
+ assert_equal Time, time.class
+ assert_equal time.object_id, @twz.to_time.object_id
+ assert_equal Time.local(1999, 12, 31, 19), time
+ assert_equal Time.local(1999, 12, 31, 19).utc_offset, time.utc_offset
+ end
end
end
diff --git a/activesupport/test/time_zone_test_helpers.rb b/activesupport/test/time_zone_test_helpers.rb
index 719f11b6bf..312d5a2c9a 100644
--- a/activesupport/test/time_zone_test_helpers.rb
+++ b/activesupport/test/time_zone_test_helpers.rb
@@ -16,6 +16,20 @@ def with_env_tz(new_tz = "US/Eastern")
old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
end
+ def with_preserve_timezone(value)
+ old_preserve_tz = ActiveSupport.to_time_preserves_timezone
+
+ ActiveSupport.deprecator.silence do
+ ActiveSupport.to_time_preserves_timezone = value
+ end
+
+ yield
+ ensure
+ ActiveSupport.deprecator.silence do
+ ActiveSupport.to_time_preserves_timezone = old_preserve_tz
+ end
+ end
+
def with_tz_mappings(mappings)
old_mappings = ActiveSupport::TimeZone::MAPPING.dup
ActiveSupport::TimeZone.clear
diff --git a/guides/source/7_2_release_notes.md b/guides/source/7_2_release_notes.md
index c1df823c75..4aee241d35 100644
--- a/guides/source/7_2_release_notes.md
+++ b/guides/source/7_2_release_notes.md
@@ -546,14 +546,8 @@ Please refer to the [Changelog][active-support] for detailed changes.
* Remove deprecated support to passing `Dalli::Client` instances to `MemCacheStore`.
-* Remove deprecated support for the pre-Ruby 2.4 behavior of `to_time` returning a `Time` object with local timezone.
-
### Deprecations
-* Deprecate `config.active_support.to_time_preserves_timezone`.
-
-* Deprecate `DateAndTime::Compatibility.preserve_timezone`.
-
### Notable changes
Active Job
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 7995d83522..168e7b313b 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -154,6 +154,7 @@ Below are the default values associated with each target version. In cases of co
#### Default Values for Target Version 5.0
+- [`ActiveSupport.to_time_preserves_timezone`](#activesupport-to-time-preserves-timezone): `true`
- [`config.action_controller.forgery_protection_origin_check`](#config-action-controller-forgery-protection-origin-check): `true`
- [`config.action_controller.per_form_csrf_tokens`](#config-action-controller-per-form-csrf-tokens): `true`
- [`config.active_record.belongs_to_required_by_default`](#config-active-record-belongs-to-required-by-default): `true`
@@ -2695,6 +2696,17 @@ Is set to `false` to disable the ability to silence logging in a block. The defa
Specifies the logger to use within cache store operations.
+#### `ActiveSupport.to_time_preserves_timezone`
+
+Specifies whether `to_time` methods preserve the UTC offset of their receivers. If `false`, `to_time` methods will convert to the local system UTC offset instead.
+
+The default value depends on the `config.load_defaults` target version:
+
+| Starting with version | The default value is |
+| --------------------- | -------------------- |
+| (original) | `false` |
+| 5.0 | `true` |
+
#### `ActiveSupport.utc_to_local_returns_utc_offset_times`
Configures `ActiveSupport::TimeZone.utc_to_local` to return a time with a UTC
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index fe98cb834b..cbe19f1d3a 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -114,6 +114,8 @@ def load_defaults(target_version)
action_controller.forgery_protection_origin_check = true
end
+ ActiveSupport.to_time_preserves_timezone = true
+
if respond_to?(:active_record)
active_record.belongs_to_required_by_default = true
end
diff --git a/tools/rail_inspector/test/rail_inspector/visitor/framework_default_test.rb b/tools/rail_inspector/test/rail_inspector/visitor/framework_default_test.rb
index a22cb4f83a..f38b7ca3b1 100644
--- a/tools/rail_inspector/test/rail_inspector/visitor/framework_default_test.rb
+++ b/tools/rail_inspector/test/rail_inspector/visitor/framework_default_test.rb
@@ -7,7 +7,7 @@ def test_smoke
config = config_for_defaults <<~RUBY
case target_version.to_s
when "5.0"
- ActiveSupport.cache_format_version = 7.0
+ ActiveSupport.to_time_preserves_timezone = true
if respond_to?(:active_record)
active_record.belongs_to_required_by_default = true
@@ -27,7 +27,7 @@ def test_smoke
["5.0", "5.1"].each { |k| assert_includes(config, k) }
- assert_equal("7.0", config["5.0"]["ActiveSupport.cache_format_version"])
+ assert_equal("true", config["5.0"]["ActiveSupport.to_time_preserves_timezone"])
assert_equal("true", config["5.0"]["active_record.belongs_to_required_by_default"])
assert_equal("{ hsts: { subdomains: true } }", config["5.0"]["self.ssl_options"])
assert_equal("false", config["5.1"]["assets.unknown_asset_fallback"])