activesupport 6.0.3.4 → 6.1.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +371 -448
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support.rb +13 -1
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +3 -3
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache.rb +85 -44
- data/lib/active_support/cache/file_store.rb +4 -3
- data/lib/active_support/cache/mem_cache_store.rb +29 -18
- data/lib/active_support/cache/memory_store.rb +46 -26
- data/lib/active_support/cache/redis_cache_store.rb +27 -27
- data/lib/active_support/cache/strategy/local_cache.rb +21 -6
- data/lib/active_support/callbacks.rb +65 -56
- data/lib/active_support/concern.rb +46 -2
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext.rb +1 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +17 -38
- data/lib/active_support/core_ext/date/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/enumerable.rb +76 -4
- data/lib/active_support/core_ext/hash/conversions.rb +2 -2
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +38 -28
- data/lib/active_support/core_ext/module/introspection.rb +1 -25
- data/lib/active_support/core_ext/name_error.rb +29 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +13 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/range/compare_range.rb +9 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/inflections.rb +38 -4
- data/lib/active_support/core_ext/string/inquiry.rb +1 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +10 -10
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/time/calculations.rb +27 -3
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +5 -1
- data/lib/active_support/current_attributes.rb +7 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/dependencies.rb +43 -19
- data/lib/active_support/deprecation.rb +6 -1
- data/lib/active_support/deprecation/behaviors.rb +15 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +0 -1
- data/lib/active_support/deprecation/method_wrappers.rb +3 -2
- data/lib/active_support/deprecation/proxy_wrappers.rb +3 -3
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/descendants_tracker.rb +6 -2
- data/lib/active_support/duration.rb +71 -22
- data/lib/active_support/duration/iso8601_serializer.rb +15 -9
- data/lib/active_support/encrypted_file.rb +19 -2
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +69 -133
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +43 -24
- data/lib/active_support/i18n_railtie.rb +14 -19
- data/lib/active_support/inflector/inflections.rb +1 -2
- data/lib/active_support/inflector/methods.rb +35 -31
- data/lib/active_support/inflector/transliterate.rb +4 -4
- data/lib/active_support/json/decoding.rb +4 -4
- data/lib/active_support/json/encoding.rb +5 -1
- data/lib/active_support/key_generator.rb +1 -1
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber.rb +8 -0
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +34 -12
- data/lib/active_support/message_encryptor.rb +4 -7
- data/lib/active_support/message_verifier.rb +5 -5
- data/lib/active_support/messages/metadata.rb +9 -1
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +6 -5
- data/lib/active_support/multibyte/chars.rb +4 -42
- data/lib/active_support/multibyte/unicode.rb +9 -83
- data/lib/active_support/notifications.rb +32 -5
- data/lib/active_support/notifications/fanout.rb +23 -8
- data/lib/active_support/notifications/instrumenter.rb +6 -15
- data/lib/active_support/number_helper.rb +29 -14
- data/lib/active_support/number_helper/number_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -7
- data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +3 -3
- data/lib/active_support/number_helper/rounding_helper.rb +12 -28
- data/lib/active_support/option_merger.rb +3 -2
- data/lib/active_support/ordered_options.rb +8 -2
- data/lib/active_support/parameter_filter.rb +16 -11
- data/lib/active_support/per_thread_registry.rb +1 -1
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +23 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +12 -7
- data/lib/active_support/tagged_logging.rb +29 -4
- data/lib/active_support/testing/assertions.rb +18 -11
- data/lib/active_support/testing/parallelization.rb +12 -95
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/time_helpers.rb +40 -3
- data/lib/active_support/time_with_zone.rb +67 -43
- data/lib/active_support/values/time_zone.rb +20 -10
- data/lib/active_support/xml_mini/rexml.rb +8 -1
- metadata +34 -36
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
- data/lib/active_support/core_ext/hash/compact.rb +0 -5
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
- data/lib/active_support/core_ext/module/reachable.rb +0 -6
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
- data/lib/active_support/core_ext/range/include_range.rb +0 -9
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "drb"
|
4
|
+
require "drb/unix" unless Gem.win_platform?
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module Testing
|
8
|
+
class Parallelization # :nodoc:
|
9
|
+
class Server
|
10
|
+
include DRb::DRbUndumped
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@queue = Queue.new
|
14
|
+
@active_workers = Concurrent::Map.new
|
15
|
+
@in_flight = Concurrent::Map.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def record(reporter, result)
|
19
|
+
raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown)
|
20
|
+
|
21
|
+
@in_flight.delete([result.klass, result.name])
|
22
|
+
|
23
|
+
reporter.synchronize do
|
24
|
+
reporter.record(result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def <<(o)
|
29
|
+
o[2] = DRbObject.new(o[2]) if o
|
30
|
+
@queue << o
|
31
|
+
end
|
32
|
+
|
33
|
+
def pop
|
34
|
+
if test = @queue.pop
|
35
|
+
@in_flight[[test[0].to_s, test[1]]] = test
|
36
|
+
test
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def start_worker(worker_id)
|
41
|
+
@active_workers[worker_id] = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def stop_worker(worker_id)
|
45
|
+
@active_workers.delete(worker_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
def active_workers?
|
49
|
+
@active_workers.size > 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def shutdown
|
53
|
+
# Wait for initial queue to drain
|
54
|
+
while @queue.length != 0
|
55
|
+
sleep 0.1
|
56
|
+
end
|
57
|
+
|
58
|
+
@queue.close
|
59
|
+
|
60
|
+
# Wait until all workers have finished
|
61
|
+
while active_workers?
|
62
|
+
sleep 0.1
|
63
|
+
end
|
64
|
+
|
65
|
+
@in_flight.values.each do |(klass, name, reporter)|
|
66
|
+
result = Minitest::Result.from(klass.new(name))
|
67
|
+
error = RuntimeError.new("result not reported")
|
68
|
+
error.set_backtrace([""])
|
69
|
+
result.failures << Minitest::UnexpectedError.new(error)
|
70
|
+
reporter.synchronize do
|
71
|
+
reporter.record(result)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
class Parallelization # :nodoc:
|
6
|
+
class Worker
|
7
|
+
def initialize(number, url)
|
8
|
+
@id = SecureRandom.uuid
|
9
|
+
@number = number
|
10
|
+
@url = url
|
11
|
+
@setup_exception = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
fork do
|
16
|
+
set_process_title("(starting)")
|
17
|
+
|
18
|
+
DRb.stop_service
|
19
|
+
|
20
|
+
@queue = DRbObject.new_with_uri(@url)
|
21
|
+
@queue.start_worker(@id)
|
22
|
+
|
23
|
+
begin
|
24
|
+
after_fork
|
25
|
+
rescue => @setup_exception; end
|
26
|
+
|
27
|
+
work_from_queue
|
28
|
+
ensure
|
29
|
+
set_process_title("(stopping)")
|
30
|
+
|
31
|
+
run_cleanup
|
32
|
+
@queue.stop_worker(@id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def work_from_queue
|
37
|
+
while job = @queue.pop
|
38
|
+
perform_job(job)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def perform_job(job)
|
43
|
+
klass = job[0]
|
44
|
+
method = job[1]
|
45
|
+
reporter = job[2]
|
46
|
+
|
47
|
+
set_process_title("#{klass}##{method}")
|
48
|
+
|
49
|
+
result = klass.with_info_handler reporter do
|
50
|
+
Minitest.run_one_method(klass, method)
|
51
|
+
end
|
52
|
+
|
53
|
+
safe_record(reporter, result)
|
54
|
+
end
|
55
|
+
|
56
|
+
def safe_record(reporter, result)
|
57
|
+
add_setup_exception(result) if @setup_exception
|
58
|
+
|
59
|
+
begin
|
60
|
+
@queue.record(reporter, result)
|
61
|
+
rescue DRb::DRbConnError
|
62
|
+
result.failures.map! do |failure|
|
63
|
+
if failure.respond_to?(:error)
|
64
|
+
# minitest >5.14.0
|
65
|
+
error = DRb::DRbRemoteError.new(failure.error)
|
66
|
+
else
|
67
|
+
error = DRb::DRbRemoteError.new(failure.exception)
|
68
|
+
end
|
69
|
+
Minitest::UnexpectedError.new(error)
|
70
|
+
end
|
71
|
+
@queue.record(reporter, result)
|
72
|
+
end
|
73
|
+
|
74
|
+
set_process_title("(idle)")
|
75
|
+
end
|
76
|
+
|
77
|
+
def after_fork
|
78
|
+
Parallelization.after_fork_hooks.each do |cb|
|
79
|
+
cb.call(@number)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def run_cleanup
|
84
|
+
Parallelization.run_cleanup_hooks.each do |cb|
|
85
|
+
cb.call(@number)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def add_setup_exception(result)
|
91
|
+
result.failures.prepend Minitest::UnexpectedError.new(@setup_exception)
|
92
|
+
end
|
93
|
+
|
94
|
+
def set_process_title(status)
|
95
|
+
Process.setproctitle("Rails test worker #{@number} - #{status}")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -6,6 +6,7 @@ require "concurrent/map"
|
|
6
6
|
|
7
7
|
module ActiveSupport
|
8
8
|
module Testing
|
9
|
+
# Manages stubs for TimeHelpers
|
9
10
|
class SimpleStubs # :nodoc:
|
10
11
|
Stub = Struct.new(:object, :method_name, :original_method)
|
11
12
|
|
@@ -13,6 +14,13 @@ module ActiveSupport
|
|
13
14
|
@stubs = Concurrent::Map.new { |h, k| h[k] = {} }
|
14
15
|
end
|
15
16
|
|
17
|
+
# Stubs object.method_name with the given block
|
18
|
+
# If the method is already stubbed, remove that stub
|
19
|
+
# so that removing this stub will restore the original implementation.
|
20
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
21
|
+
# target = Time.zone.local(2004, 11, 24, 1, 4, 44)
|
22
|
+
# simple_stubs.stub_object(Time, :now) { at(target.to_i) }
|
23
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
16
24
|
def stub_object(object, method_name, &block)
|
17
25
|
if stub = stubbing(object, method_name)
|
18
26
|
unstub_object(stub)
|
@@ -26,6 +34,7 @@ module ActiveSupport
|
|
26
34
|
object.define_singleton_method(method_name, &block)
|
27
35
|
end
|
28
36
|
|
37
|
+
# Remove all object-method stubs held by this instance
|
29
38
|
def unstub_all!
|
30
39
|
@stubs.each_value do |object_stubs|
|
31
40
|
object_stubs.each_value do |stub|
|
@@ -35,11 +44,19 @@ module ActiveSupport
|
|
35
44
|
@stubs.clear
|
36
45
|
end
|
37
46
|
|
47
|
+
# Returns the Stub for object#method_name
|
48
|
+
# (nil if it is not stubbed)
|
38
49
|
def stubbing(object, method_name)
|
39
50
|
@stubs[object.object_id][method_name]
|
40
51
|
end
|
41
52
|
|
53
|
+
# Returns true if any stubs are set, false if there are none
|
54
|
+
def stubbed?
|
55
|
+
!@stubs.empty?
|
56
|
+
end
|
57
|
+
|
42
58
|
private
|
59
|
+
# Restores the original object.method described by the Stub
|
43
60
|
def unstub_object(stub)
|
44
61
|
singleton_class = stub.object.singleton_class
|
45
62
|
singleton_class.silence_redefinition_of_method stub.method_name
|
@@ -82,7 +99,7 @@ module ActiveSupport
|
|
82
99
|
# The stubs are automatically removed at the end of the test.
|
83
100
|
#
|
84
101
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
85
|
-
# travel_to Time.zone.local(2004, 11, 24,
|
102
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
86
103
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
87
104
|
# Date.current # => Wed, 24 Nov 2004
|
88
105
|
# DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
|
@@ -104,7 +121,7 @@ module ActiveSupport
|
|
104
121
|
# state at the end of the block:
|
105
122
|
#
|
106
123
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
107
|
-
# travel_to Time.zone.local(2004, 11, 24,
|
124
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
|
108
125
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
109
126
|
# end
|
110
127
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
@@ -160,12 +177,32 @@ module ActiveSupport
|
|
160
177
|
# +travel+, +travel_to+, and +freeze_time+.
|
161
178
|
#
|
162
179
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
163
|
-
#
|
180
|
+
#
|
181
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
164
182
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
183
|
+
#
|
165
184
|
# travel_back
|
166
185
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
186
|
+
#
|
187
|
+
# This method also accepts a block, which brings the stubs back at the end of the block:
|
188
|
+
#
|
189
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
190
|
+
#
|
191
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
192
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
193
|
+
#
|
194
|
+
# travel_back do
|
195
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
196
|
+
# end
|
197
|
+
#
|
198
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
167
199
|
def travel_back
|
200
|
+
stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
|
201
|
+
|
168
202
|
simple_stubs.unstub_all!
|
203
|
+
yield if block_given?
|
204
|
+
ensure
|
205
|
+
travel_to stubbed_time if stubbed_time
|
169
206
|
end
|
170
207
|
alias_method :unfreeze_time, :travel_back
|
171
208
|
|
@@ -15,25 +15,25 @@ module ActiveSupport
|
|
15
15
|
# and +in_time_zone+ on Time and DateTime instances.
|
16
16
|
#
|
17
17
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
18
|
-
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
19
|
-
# Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
20
|
-
# Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
21
|
-
# Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00
|
22
|
-
# Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
18
|
+
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
|
19
|
+
# Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
|
20
|
+
# Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
|
21
|
+
# Time.zone.now # => Sun, 18 May 2008 13:07:55.754107581 EDT -04:00
|
22
|
+
# Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
|
23
23
|
#
|
24
24
|
# See Time and TimeZone for further documentation of these methods.
|
25
25
|
#
|
26
26
|
# TimeWithZone instances implement the same API as Ruby Time instances, so
|
27
27
|
# that Time and TimeWithZone instances are interchangeable.
|
28
28
|
#
|
29
|
-
# t = Time.zone.now # => Sun, 18 May 2008 13:27:25 EDT -04:00
|
29
|
+
# t = Time.zone.now # => Sun, 18 May 2008 13:27:25.031505668 EDT -04:00
|
30
30
|
# t.hour # => 13
|
31
31
|
# t.dst? # => true
|
32
32
|
# t.utc_offset # => -14400
|
33
33
|
# t.zone # => "EDT"
|
34
34
|
# t.to_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
|
35
|
-
# t + 1.day # => Mon, 19 May 2008 13:27:25 EDT -04:00
|
36
|
-
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00 EST -05:00
|
35
|
+
# t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
|
36
|
+
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00
|
37
37
|
# t > Time.utc(1999) # => true
|
38
38
|
# t.is_a?(Time) # => true
|
39
39
|
# t.is_a?(ActiveSupport::TimeWithZone) # => true
|
@@ -57,12 +57,12 @@ module ActiveSupport
|
|
57
57
|
|
58
58
|
# Returns a <tt>Time</tt> instance that represents the time in +time_zone+.
|
59
59
|
def time
|
60
|
-
@time ||=
|
60
|
+
@time ||= incorporate_utc_offset(@utc, utc_offset)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
|
64
64
|
def utc
|
65
|
-
@utc ||=
|
65
|
+
@utc ||= incorporate_utc_offset(@time, -utc_offset)
|
66
66
|
end
|
67
67
|
alias_method :comparable_time, :utc
|
68
68
|
alias_method :getgm, :utc
|
@@ -104,13 +104,13 @@ module ActiveSupport
|
|
104
104
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
105
105
|
# Time.zone.now.utc? # => false
|
106
106
|
def utc?
|
107
|
-
|
107
|
+
zone == "UTC" || zone == "UCT"
|
108
108
|
end
|
109
109
|
alias_method :gmt?, :utc?
|
110
110
|
|
111
111
|
# Returns the offset from current time to UTC time in seconds.
|
112
112
|
def utc_offset
|
113
|
-
period.
|
113
|
+
period.observed_utc_offset
|
114
114
|
end
|
115
115
|
alias_method :gmt_offset, :utc_offset
|
116
116
|
alias_method :gmtoff, :utc_offset
|
@@ -132,14 +132,14 @@ module ActiveSupport
|
|
132
132
|
# Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)"
|
133
133
|
# Time.zone.now.zone # => "EST"
|
134
134
|
def zone
|
135
|
-
period.
|
135
|
+
period.abbreviation
|
136
136
|
end
|
137
137
|
|
138
138
|
# Returns a string of the object's date, time, zone, and offset from UTC.
|
139
139
|
#
|
140
|
-
# Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25 EST -05:00"
|
140
|
+
# Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25.624541392 EST -05:00"
|
141
141
|
def inspect
|
142
|
-
"#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
|
142
|
+
"#{time.strftime('%a, %d %b %Y %H:%M:%S.%9N')} #{zone} #{formatted_offset}"
|
143
143
|
end
|
144
144
|
|
145
145
|
# Returns a string of the object's date and time in the ISO 8601 standard
|
@@ -245,6 +245,20 @@ module ActiveSupport
|
|
245
245
|
time.today?
|
246
246
|
end
|
247
247
|
|
248
|
+
# Returns true if the current object's time falls within
|
249
|
+
# the next day (tomorrow).
|
250
|
+
def tomorrow?
|
251
|
+
time.tomorrow?
|
252
|
+
end
|
253
|
+
alias :next_day? :tomorrow?
|
254
|
+
|
255
|
+
# Returns true if the current object's time falls within
|
256
|
+
# the previous day (yesterday).
|
257
|
+
def yesterday?
|
258
|
+
time.yesterday?
|
259
|
+
end
|
260
|
+
alias :prev_day? :yesterday?
|
261
|
+
|
248
262
|
# Returns true if the current object's time is in the future.
|
249
263
|
def future?
|
250
264
|
utc.future?
|
@@ -263,8 +277,8 @@ module ActiveSupport
|
|
263
277
|
# value as a new TimeWithZone object.
|
264
278
|
#
|
265
279
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
266
|
-
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
267
|
-
# now + 1000 # => Sun, 02 Nov 2014 01:43:08 EDT -04:00
|
280
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00
|
281
|
+
# now + 1000 # => Sun, 02 Nov 2014 01:43:08.725182881 EDT -04:00
|
268
282
|
#
|
269
283
|
# If we're adding a Duration of variable length (i.e., years, months, days),
|
270
284
|
# move forward from #time, otherwise move forward from #utc, for accuracy
|
@@ -273,8 +287,8 @@ module ActiveSupport
|
|
273
287
|
# For instance, a time + 24.hours will advance exactly 24 hours, while a
|
274
288
|
# time + 1.day will advance 23-25 hours, depending on the day.
|
275
289
|
#
|
276
|
-
# now + 24.hours # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
277
|
-
# now + 1.day # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
290
|
+
# now + 24.hours # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
|
291
|
+
# now + 1.day # => Mon, 03 Nov 2014 01:26:28.725182881 EST -05:00
|
278
292
|
def +(other)
|
279
293
|
if duration_of_variable_length?(other)
|
280
294
|
method_missing(:+, other)
|
@@ -287,13 +301,13 @@ module ActiveSupport
|
|
287
301
|
alias_method :in, :+
|
288
302
|
|
289
303
|
# Subtracts an interval of time and returns a new TimeWithZone object unless
|
290
|
-
# the other value
|
304
|
+
# the other value +acts_like?+ time. Then it will return a Float of the difference
|
291
305
|
# between the two times that represents the difference between the current
|
292
306
|
# object's time and the +other+ time.
|
293
307
|
#
|
294
308
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
295
|
-
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
296
|
-
# now - 1000 # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
309
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
|
310
|
+
# now - 1000 # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00
|
297
311
|
#
|
298
312
|
# If subtracting a Duration of variable length (i.e., years, months, days),
|
299
313
|
# move backward from #time, otherwise move backward from #utc, for accuracy
|
@@ -302,8 +316,8 @@ module ActiveSupport
|
|
302
316
|
# For instance, a time - 24.hours will go subtract exactly 24 hours, while a
|
303
317
|
# time - 1.day will subtract 23-25 hours, depending on the day.
|
304
318
|
#
|
305
|
-
# now - 24.hours # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
306
|
-
# now - 1.day # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
319
|
+
# now - 24.hours # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00
|
320
|
+
# now - 1.day # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
|
307
321
|
#
|
308
322
|
# If both the TimeWithZone object and the other value act like Time, a Float
|
309
323
|
# will be returned.
|
@@ -325,8 +339,8 @@ module ActiveSupport
|
|
325
339
|
# the result as a new TimeWithZone object.
|
326
340
|
#
|
327
341
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
328
|
-
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
329
|
-
# now.ago(1000) # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
342
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
|
343
|
+
# now.ago(1000) # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00
|
330
344
|
#
|
331
345
|
# If we're subtracting a Duration of variable length (i.e., years, months,
|
332
346
|
# days), move backward from #time, otherwise move backward from #utc, for
|
@@ -336,8 +350,8 @@ module ActiveSupport
|
|
336
350
|
# while <tt>time.ago(1.day)</tt> will move back 23-25 hours, depending on
|
337
351
|
# the day.
|
338
352
|
#
|
339
|
-
# now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
340
|
-
# now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
353
|
+
# now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00
|
354
|
+
# now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
|
341
355
|
def ago(other)
|
342
356
|
since(-other)
|
343
357
|
end
|
@@ -353,12 +367,12 @@ module ActiveSupport
|
|
353
367
|
# or <tt>:nsec</tt>, not both. Similarly, pass either <tt>:zone</tt> or
|
354
368
|
# <tt>:offset</tt>, not both.
|
355
369
|
#
|
356
|
-
# t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15 EST -05:00
|
357
|
-
# t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15 EST -05:00
|
358
|
-
# t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00 EST -05:00
|
359
|
-
# t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00 EST -05:00
|
360
|
-
# t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
|
361
|
-
# t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
|
370
|
+
# t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15.116992711 EST -05:00
|
371
|
+
# t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15.116992711 EST -05:00
|
372
|
+
# t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00.116992711 EST -05:00
|
373
|
+
# t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00.116992711 EST -05:00
|
374
|
+
# t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
|
375
|
+
# t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
|
362
376
|
def change(options)
|
363
377
|
if options[:zone] && options[:offset]
|
364
378
|
raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}"
|
@@ -391,14 +405,14 @@ module ActiveSupport
|
|
391
405
|
# accuracy when moving across DST boundaries.
|
392
406
|
#
|
393
407
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
394
|
-
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
395
|
-
# now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29 EDT -04:00
|
396
|
-
# now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28 EDT -04:00
|
397
|
-
# now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28 EST -05:00
|
398
|
-
# now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
399
|
-
# now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28 EST -05:00
|
400
|
-
# now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28 EST -05:00
|
401
|
-
# now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28 EST -05:00
|
408
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.558049687 EDT -04:00
|
409
|
+
# now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29.558049687 EDT -04:00
|
410
|
+
# now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28.558049687 EDT -04:00
|
411
|
+
# now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28.558049687 EST -05:00
|
412
|
+
# now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28.558049687 EST -05:00
|
413
|
+
# now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28.558049687 EST -05:00
|
414
|
+
# now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28.558049687 EST -05:00
|
415
|
+
# now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28.558049687 EST -05:00
|
402
416
|
def advance(options)
|
403
417
|
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
|
404
418
|
# otherwise advance from #utc, for accuracy when moving across DST boundaries
|
@@ -420,7 +434,7 @@ module ActiveSupport
|
|
420
434
|
# Returns Array of parts of Time in sequence of
|
421
435
|
# [seconds, minutes, hours, day, month, year, weekday, yearday, dst?, zone].
|
422
436
|
#
|
423
|
-
# now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27 UTC +00:00
|
437
|
+
# now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27.485278555 UTC +00:00
|
424
438
|
# now.to_a # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
|
425
439
|
def to_a
|
426
440
|
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
@@ -524,6 +538,16 @@ module ActiveSupport
|
|
524
538
|
end
|
525
539
|
|
526
540
|
private
|
541
|
+
SECONDS_PER_DAY = 86400
|
542
|
+
|
543
|
+
def incorporate_utc_offset(time, offset)
|
544
|
+
if time.kind_of?(Date)
|
545
|
+
time + Rational(offset, SECONDS_PER_DAY)
|
546
|
+
else
|
547
|
+
time + offset
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
527
551
|
def get_period_and_ensure_valid_local_time(period)
|
528
552
|
# we don't want a Time.local instance enforcing its own DST rules as well,
|
529
553
|
# so transfer time values to a utc constructor if necessary
|