Add a config for preserving timezone information
when calling `to_time` on TimeWithZone object Co-authored-by: jhawthorn <jhawthorn@github.com>
This commit is contained in:
parent
f5355a21ae
commit
9dcf17ec4c
@ -8,4 +8,8 @@
|
||||
|
||||
*Richard Böhme*, *Jean Boussier*
|
||||
|
||||
* Add a new configuration value `:zone` for `ActiveSupport.to_time_preserves_timezone` and rename the previous `true` value to `:offset`. The new default value is `:zone`.
|
||||
|
||||
*Jason Kim*, *John Hawthorn*
|
||||
|
||||
Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activesupport/CHANGELOG.md) for previous changes.
|
||||
|
@ -115,9 +115,15 @@ def self.to_time_preserves_timezone
|
||||
end
|
||||
|
||||
def self.to_time_preserves_timezone=(value)
|
||||
unless value
|
||||
if !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."
|
||||
"`to_time` will always preserve the receiver timezone rather than system local time in Rails 8.0." \
|
||||
"To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`."
|
||||
)
|
||||
elsif value != :zone
|
||||
ActiveSupport.deprecator.warn(
|
||||
"`to_time` will always preserve the full timezone rather than offset of the receiver in Rails 8.0. " \
|
||||
"To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`."
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -26,8 +26,8 @@ def self.preserve_timezone # :nodoc:
|
||||
# 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`."
|
||||
"`to_time` will always preserve the receiver timezone rather than system local time in Rails 8.0." \
|
||||
"To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`."
|
||||
)
|
||||
|
||||
@@preserve_timezone = false
|
||||
|
@ -96,6 +96,10 @@ class Railtie < Rails::Railtie # :nodoc:
|
||||
config.eager_load_namespaces << TZInfo
|
||||
end
|
||||
|
||||
initializer "active_support.to_time_preserves_timezone" do |app|
|
||||
ActiveSupport.to_time_preserves_timezone = app.config.active_support.to_time_preserves_timezone
|
||||
end
|
||||
|
||||
# Sets the default week start
|
||||
# If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
|
||||
initializer "active_support.initialize_beginning_of_week" do |app|
|
||||
|
@ -479,11 +479,13 @@ def to_datetime
|
||||
@to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
|
||||
end
|
||||
|
||||
# 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+.
|
||||
# Returns an instance of +Time+, either with the same timezone as +self+,
|
||||
# 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
|
||||
if preserve_timezone
|
||||
if preserve_timezone == :zone
|
||||
@to_time_with_timezone ||= getlocal(time_zone)
|
||||
elsif preserve_timezone
|
||||
@to_time_with_instance_offset ||= getlocal(utc_offset)
|
||||
else
|
||||
@to_time_with_system_offset ||= getlocal
|
||||
|
@ -280,8 +280,8 @@ def test_to_time_preserves_timezone_is_deprecated
|
||||
ActiveSupport.to_time_preserves_timezone
|
||||
end
|
||||
|
||||
assert_not_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = true
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = :offset
|
||||
end
|
||||
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
@ -306,4 +306,36 @@ def test_to_time_preserves_timezone_is_deprecated
|
||||
ActiveSupport.to_time_preserves_timezone = current_preserve_tz
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_time_preserves_timezone_supports_new_values
|
||||
current_preserve_tz = ActiveSupport.to_time_preserves_timezone
|
||||
|
||||
assert_not_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone
|
||||
end
|
||||
|
||||
assert_not_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = :zone
|
||||
end
|
||||
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = :offset
|
||||
end
|
||||
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = true
|
||||
end
|
||||
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = "offset"
|
||||
end
|
||||
|
||||
assert_deprecated(ActiveSupport.deprecator) do
|
||||
ActiveSupport.to_time_preserves_timezone = :foo
|
||||
end
|
||||
ensure
|
||||
ActiveSupport.deprecator.silence do
|
||||
ActiveSupport.to_time_preserves_timezone = current_preserve_tz
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -517,7 +517,34 @@ def test_time_at
|
||||
assert_equal time, Time.at(time)
|
||||
end
|
||||
|
||||
def test_to_time_with_preserve_timezone
|
||||
def test_to_time_with_preserve_timezone_using_zone
|
||||
with_preserve_timezone(:zone) do
|
||||
time = @twz.to_time
|
||||
local_time = with_env_tz("US/Eastern") { Time.local(1999, 12, 31, 19) }
|
||||
|
||||
assert_equal Time, time.class
|
||||
assert_equal time.object_id, @twz.to_time.object_id
|
||||
assert_equal local_time, time
|
||||
assert_equal local_time.utc_offset, time.utc_offset
|
||||
assert_equal @time_zone, time.zone
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_time_with_preserve_timezone_using_offset
|
||||
with_preserve_timezone(:offset) 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_nil time.zone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_time_with_preserve_timezone_using_true
|
||||
with_preserve_timezone(true) do
|
||||
with_env_tz "US/Eastern" do
|
||||
time = @twz.to_time
|
||||
@ -526,6 +553,7 @@ def test_to_time_with_preserve_timezone
|
||||
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_nil time.zone
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -539,6 +567,7 @@ def test_to_time_without_preserve_timezone
|
||||
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.local(1999, 12, 31, 19).zone, time.zone
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -552,6 +581,7 @@ def test_to_time_without_preserve_timezone_configured
|
||||
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.local(1999, 12, 31, 19).zone, time.zone
|
||||
|
||||
assert_equal false, ActiveSupport.to_time_preserves_timezone
|
||||
end
|
||||
|
@ -58,6 +58,10 @@ NOTE: If you need to apply configuration directly to a class, use a [lazy load h
|
||||
|
||||
Below are the default values associated with each target version. In cases of conflicting values, newer versions take precedence over older versions.
|
||||
|
||||
#### Default Values for Target Version 8.0
|
||||
|
||||
- [`config.active_support.to_time_preserves_timezone`](#config-active-support-to-time-preserves-timezone): `:zone`
|
||||
|
||||
#### Default Values for Target Version 7.2
|
||||
|
||||
- [`config.active_job.enqueue_after_transaction_commit`](#config-active-job-enqueue-after-transaction-commit): `:default`
|
||||
@ -154,10 +158,10 @@ 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`
|
||||
- [`config.active_support.to_time_preserves_timezone`](#config-active-support-to-time-preserves-timezone): `:offset`
|
||||
- [`config.ssl_options`](#config-ssl-options): `{ hsts: { subdomains: true } }`
|
||||
|
||||
### Rails General Configuration
|
||||
@ -2694,6 +2698,18 @@ The default value depends on the `config.load_defaults` target version:
|
||||
| (original) | `false` |
|
||||
| 7.0 | `true` |
|
||||
|
||||
#### `config.active_support.to_time_preserves_timezone`
|
||||
|
||||
Specifies whether `to_time` methods preserve the UTC offset of their receivers or preserves the timezone. If set to `:zone`, `to_time` methods will use the timezone of their receivers. If set to `:offset`, `to_time` methods will use the UTC offset. 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 | `:offset` |
|
||||
| 8.0 | `:zone` |
|
||||
|
||||
#### `ActiveSupport::Logger.silencer`
|
||||
|
||||
Is set to `false` to disable the ability to silence logging in a block. The default is `true`.
|
||||
@ -2702,17 +2718,6 @@ 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
|
||||
|
@ -114,7 +114,9 @@ def load_defaults(target_version)
|
||||
action_controller.forgery_protection_origin_check = true
|
||||
end
|
||||
|
||||
ActiveSupport.to_time_preserves_timezone = true
|
||||
if respond_to?(:active_support)
|
||||
active_support.to_time_preserves_timezone = :offset
|
||||
end
|
||||
|
||||
if respond_to?(:active_record)
|
||||
active_record.belongs_to_required_by_default = true
|
||||
@ -337,6 +339,10 @@ def load_defaults(target_version)
|
||||
end
|
||||
when "8.0"
|
||||
load_defaults "7.2"
|
||||
|
||||
if respond_to?(:active_support)
|
||||
active_support.to_time_preserves_timezone = :zone
|
||||
end
|
||||
else
|
||||
raise "Unknown version #{target_version.to_s.inspect}"
|
||||
end
|
||||
|
@ -8,3 +8,11 @@
|
||||
#
|
||||
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
||||
|
||||
###
|
||||
# Specifies whether `to_time` methods preserve the UTC offset of their receivers or preserves the timezone.
|
||||
# If set to `:zone`, `to_time` methods will use the timezone of their receivers.
|
||||
# If set to `:offset`, `to_time` methods will use the UTC offset.
|
||||
# If `false`, `to_time` methods will convert to the local system UTC offset instead.
|
||||
#++
|
||||
# Rails.application.config.active_support.to_time_preserves_timezone = :zone
|
||||
|
Loading…
Reference in New Issue
Block a user