Skip to content

Commit f4c39b5

Browse files
authored
Merge pull request rails#51994 from matthewd/preserves-timezone-very-deprecated
Re-roll deprecation of to_time_preserves_timezone
2 parents 5ade5d4 + 595c3cc commit f4c39b5

File tree

15 files changed

+384
-120
lines changed

15 files changed

+384
-120
lines changed

activesupport/lib/active_support.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,17 @@ def self.cache_format_version=(value)
111111
end
112112

113113
def self.to_time_preserves_timezone
114-
ActiveSupport.deprecator.warn(
115-
"`config.active_support.to_time_preserves_timezone` has been deprecated and will be removed in Rails 7.3."
116-
)
114+
DateAndTime::Compatibility.preserve_timezone
117115
end
118116

119117
def self.to_time_preserves_timezone=(value)
120-
ActiveSupport.deprecator.warn(
121-
"`config.active_support.to_time_preserves_timezone` has been deprecated and will be removed in Rails 7.3."
122-
)
118+
unless value
119+
ActiveSupport.deprecator.warn(
120+
"Support for the pre-Ruby 2.4 behavior of to_time has been deprecated and will be removed in Rails 8.0."
121+
)
122+
end
123+
124+
DateAndTime::Compatibility.preserve_timezone = value
123125
end
124126

125127
def self.utc_to_local_returns_utc_offset_times
Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,45 @@
11
# frozen_string_literal: true
22

33
require "active_support/core_ext/module/attribute_accessors"
4+
require "active_support/core_ext/module/redefine_method"
45

56
module DateAndTime
67
module Compatibility
8+
# If true, +to_time+ preserves the timezone offset of receiver.
9+
#
10+
# NOTE: With Ruby 2.4+ the default for +to_time+ changed from
11+
# converting to the local system time, to preserving the offset
12+
# of the receiver. For backwards compatibility we're overriding
13+
# this behavior, but new apps will have an initializer that sets
14+
# this to true, because the new behavior is preferred.
15+
mattr_accessor :preserve_timezone, instance_accessor: false, default: nil
16+
17+
singleton_class.silence_redefinition_of_method :preserve_timezone
18+
19+
#--
20+
# This re-implements the behaviour of the mattr_reader, instead
21+
# of prepending on to it, to avoid overcomplicating a module that
22+
# is in turn included in several places. This will all go away in
23+
# Rails 8.0 anyway.
24+
def self.preserve_timezone # :nodoc:
25+
if @@preserve_timezone.nil?
26+
# Only warn once, the first time the value is used (which should
27+
# be the first time #to_time is called).
28+
ActiveSupport.deprecator.warn(
29+
"to_time will always preserve the timezone offset of the receiver in Rails 8.0. " \
30+
"To opt in to the new behavior, set `ActiveSupport.to_time_preserves_timezone = true`."
31+
)
32+
33+
@@preserve_timezone = false
34+
end
35+
36+
@@preserve_timezone
37+
end
38+
39+
def preserve_timezone # :nodoc:
40+
Compatibility.preserve_timezone
41+
end
42+
743
# Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
844
#
945
# When +true+, it returns local times with a UTC offset, with +false+ local
@@ -18,17 +54,5 @@ module Compatibility
1854
# # With `utc_to_local_returns_utc_offset_times = true`, local time is returned with UTC offset:
1955
# zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 -0500
2056
mattr_accessor :utc_to_local_returns_utc_offset_times, instance_writer: false, default: false
21-
22-
def self.preserve_timezone
23-
ActiveSupport.deprecator.warn(
24-
"`DateAndTime::Compatibility.preserve_timezone` has been deprecated and will be removed in Rails 7.3."
25-
)
26-
end
27-
28-
def self.preserve_timezone=(value)
29-
ActiveSupport.deprecator.warn(
30-
"`DateAndTime::Compatibility.preserve_timezone=` has been deprecated and will be removed in Rails 7.3."
31-
)
32-
end
3357
end
3458
end

activesupport/lib/active_support/core_ext/date_time/compatibility.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ class DateTime
88

99
silence_redefinition_of_method :to_time
1010

11-
# Return an instance of +Time+ with the same UTC offset
12-
# as +self+.
11+
# Either return an instance of +Time+ with the same UTC offset
12+
# as +self+ or an instance of +Time+ representing the same time
13+
# in the local system timezone depending on the setting of
14+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
1315
def to_time
14-
getlocal(utc_offset)
16+
preserve_timezone ? getlocal(utc_offset) : getlocal
1517
end
1618
end

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ class Time
88

99
silence_redefinition_of_method :to_time
1010

11-
# Returns +self+.
11+
# Either return +self+ or the time in the local system timezone depending
12+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
1213
def to_time
13-
self
14+
preserve_timezone ? self : getlocal
1415
end
1516
end

activesupport/lib/active_support/time_with_zone.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,15 @@ def to_datetime
479479
@to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
480480
end
481481

482-
# Returns an instance of +Time+ with the same UTC offset
483-
# as +self+.
482+
# Returns an instance of +Time+, either with the same UTC offset
483+
# as +self+ or in the local system timezone depending on the setting
484+
# of +ActiveSupport.to_time_preserves_timezone+.
484485
def to_time
485-
@to_time_with_instance_offset ||= getlocal(utc_offset)
486+
if preserve_timezone
487+
@to_time_with_instance_offset ||= getlocal(utc_offset)
488+
else
489+
@to_time_with_system_offset ||= getlocal
490+
end
486491
end
487492

488493
# So that +self+ <tt>acts_like?(:time)</tt>.

activesupport/test/abstract_unit.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
# Show backtraces for deprecated behavior for quicker cleanup.
2525
ActiveSupport.deprecator.debug = true
2626

27+
# Default to Ruby 2.4+ to_time behavior but allow running tests with old behavior
28+
ActiveSupport.deprecator.silence do
29+
ActiveSupport.to_time_preserves_timezone = ENV.fetch("PRESERVE_TIMEZONES", "1") == "1"
30+
end
31+
2732
ActiveSupport::Cache.format_version = 7.1
2833

2934
# Disable available locale checks to avoid warnings running the test suite.

0 commit comments

Comments
 (0)