Skip to content

Commit

Permalink
Merge pull request rails#51994 from matthewd/preserves-timezone-very-…
Browse files Browse the repository at this point in the history
…deprecated

Re-roll deprecation of to_time_preserves_timezone
  • Loading branch information
rafaelfranca authored Jun 4, 2024
2 parents 5ade5d4 + 595c3cc commit f4c39b5
Show file tree
Hide file tree
Showing 15 changed files with 384 additions and 120 deletions.
14 changes: 8 additions & 6 deletions activesupport/lib/active_support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 8.0."
)
end

DateAndTime::Compatibility.preserve_timezone = value
end

def self.utc_to_local_returns_utc_offset_times
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,45 @@
# frozen_string_literal: true

require "active_support/core_ext/module/attribute_accessors"
require "active_support/core_ext/module/redefine_method"

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_accessor: false, default: nil

singleton_class.silence_redefinition_of_method :preserve_timezone

#--
# This re-implements the behaviour of the mattr_reader, instead
# of prepending on to it, to avoid overcomplicating a module that
# is in turn included in several places. This will all go away in
# Rails 8.0 anyway.
def self.preserve_timezone # :nodoc:
if @@preserve_timezone.nil?
# Only warn once, the first time the value is used (which should
# be the first time #to_time is called).
ActiveSupport.deprecator.warn(
"to_time will always preserve the timezone offset of the receiver in Rails 8.0. " \
"To opt in to the new behavior, set `ActiveSupport.to_time_preserves_timezone = true`."
)

@@preserve_timezone = false
end

@@preserve_timezone
end

def preserve_timezone # :nodoc:
Compatibility.preserve_timezone
end

# Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
#
# When +true+, it returns local times with a UTC offset, with +false+ local
Expand All @@ -18,17 +54,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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 8 additions & 3 deletions activesupport/lib/active_support/time_with_zone.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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+ <tt>acts_like?(:time)</tt>.
Expand Down
5 changes: 5 additions & 0 deletions activesupport/test/abstract_unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading

0 comments on commit f4c39b5

Please sign in to comment.