activesupport 5.2.4.3 → 7.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +244 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -3
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -5
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache/file_store.rb +47 -41
- data/lib/active_support/cache/mem_cache_store.rb +151 -40
- data/lib/active_support/cache/memory_store.rb +68 -34
- data/lib/active_support/cache/null_store.rb +16 -3
- data/lib/active_support/cache/redis_cache_store.rb +103 -101
- data/lib/active_support/cache/strategy/local_cache.rb +56 -64
- data/lib/active_support/cache.rb +333 -116
- data/lib/active_support/callbacks.rb +244 -128
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +72 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -3
- data/lib/active_support/configurable.rb +15 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +15 -7
- data/lib/active_support/core_ext/array/conversions.rb +18 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +2 -1
- data/lib/active_support/core_ext/benchmark.rb +2 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/attribute.rb +32 -47
- data/lib/active_support/core_ext/class/subclasses.rb +9 -22
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +15 -14
- data/lib/active_support/core_ext/date/conversions.rb +16 -15
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -51
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +241 -76
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +3 -4
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +2 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +2 -31
- data/lib/active_support/core_ext/hash/slice.rb +6 -27
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +32 -39
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +35 -28
- data/lib/active_support/core_ext/module/concerning.rb +8 -2
- data/lib/active_support/core_ext/module/delegation.rb +70 -33
- data/lib/active_support/core_ext/module/introspection.rb +16 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/conversions.rb +132 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -1
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +3 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +14 -110
- data/lib/active_support/core_ext/object/json.rb +44 -27
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +24 -14
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +23 -27
- data/lib/active_support/core_ext/range/conversions.rb +32 -30
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +1 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +8 -5
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +5 -16
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +46 -7
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +6 -5
- data/lib/active_support/core_ext/string/output_safety.rb +129 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +59 -10
- data/lib/active_support/core_ext/time/conversions.rb +15 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +7 -22
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -22
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +47 -16
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +60 -715
- data/lib/active_support/deprecation/behaviors.rb +21 -5
- 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 +18 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +31 -8
- data/lib/active_support/deprecation/reporting.rb +50 -7
- data/lib/active_support/deprecation.rb +7 -2
- data/lib/active_support/descendants_tracker.rb +190 -34
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +5 -7
- data/lib/active_support/duration/iso8601_serializer.rb +27 -15
- data/lib/active_support/duration.rb +149 -67
- data/lib/active_support/encrypted_configuration.rb +12 -5
- data/lib/active_support/encrypted_file.rb +23 -5
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +85 -122
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +44 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +73 -43
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +2 -0
- data/lib/active_support/i18n_railtie.rb +15 -8
- data/lib/active_support/inflector/inflections.rb +25 -14
- data/lib/active_support/inflector/methods.rb +38 -71
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +25 -26
- data/lib/active_support/json/encoding.rb +14 -6
- data/lib/active_support/key_generator.rb +23 -38
- data/lib/active_support/lazy_load_hooks.rb +19 -5
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +51 -11
- data/lib/active_support/logger.rb +6 -22
- data/lib/active_support/logger_silence.rb +11 -19
- data/lib/active_support/logger_thread_safe_level.rb +45 -10
- data/lib/active_support/message_encryptor.rb +20 -19
- data/lib/active_support/message_verifier.rb +53 -21
- data/lib/active_support/messages/metadata.rb +13 -4
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotator.rb +10 -9
- data/lib/active_support/multibyte/chars.rb +17 -76
- data/lib/active_support/multibyte/unicode.rb +7 -331
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +163 -37
- data/lib/active_support/notifications/instrumenter.rb +90 -11
- data/lib/active_support/notifications.rb +88 -30
- data/lib/active_support/number_helper/number_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +12 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +36 -12
- data/lib/active_support/option_merger.rb +15 -4
- data/lib/active_support/ordered_hash.rb +2 -2
- data/lib/active_support/ordered_options.rb +14 -4
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +6 -1
- data/lib/active_support/rails.rb +1 -10
- data/lib/active_support/railtie.rb +77 -5
- data/lib/active_support/reloader.rb +5 -6
- data/lib/active_support/rescuable.rb +8 -8
- data/lib/active_support/ruby_features.rb +7 -0
- 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 +2 -3
- data/lib/active_support/subscriber.rb +79 -46
- data/lib/active_support/tagged_logging.rb +58 -9
- data/lib/active_support/test_case.rb +79 -0
- data/lib/active_support/testing/assertions.rb +62 -11
- data/lib/active_support/testing/deprecation.rb +52 -2
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +4 -4
- data/lib/active_support/testing/method_call_assertions.rb +32 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +4 -7
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +60 -14
- data/lib/active_support/time_with_zone.rb +139 -64
- data/lib/active_support/values/time_zone.rb +66 -30
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -4
- data/lib/active_support/xml_mini/libxml.rb +7 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +5 -5
- data/lib/active_support/xml_mini/nokogiri.rb +6 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +4 -4
- data/lib/active_support/xml_mini/rexml.rb +11 -4
- data/lib/active_support/xml_mini.rb +7 -14
- data/lib/active_support.rb +30 -1
- metadata +64 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
- data/lib/active_support/core_ext/hash/compact.rb +0 -29
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/core_ext/marshal.rb +0 -24
- data/lib/active_support/core_ext/module/reachable.rb +0 -11
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
- data/lib/active_support/core_ext/range/include_range.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/core_ext/kernel/singleton_class"
|
4
3
|
require "active_support/core_ext/module/redefine_method"
|
5
|
-
require "active_support/core_ext/array/extract_options"
|
6
4
|
|
7
5
|
class Class
|
8
6
|
# Declare a class-level attribute whose value is inheritable by subclasses.
|
@@ -84,63 +82,50 @@ class Class
|
|
84
82
|
# To set a default value for the attribute, pass <tt>default:</tt>, like so:
|
85
83
|
#
|
86
84
|
# class_attribute :settings, default: {}
|
87
|
-
def class_attribute(*attrs
|
88
|
-
|
89
|
-
instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
|
90
|
-
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
|
91
|
-
instance_predicate = options.fetch(:instance_predicate, true)
|
92
|
-
default_value = options.fetch(:default, nil)
|
85
|
+
def class_attribute(*attrs, instance_accessor: true,
|
86
|
+
instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
|
93
87
|
|
88
|
+
class_methods, methods = [], []
|
94
89
|
attrs.each do |name|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
singleton_class.silence_redefinition_of_method("#{name}?")
|
99
|
-
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
100
|
-
|
101
|
-
ivar = "@#{name}"
|
90
|
+
unless name.is_a?(Symbol) || name.is_a?(String)
|
91
|
+
raise TypeError, "#{name.inspect} is not a symbol nor a string"
|
92
|
+
end
|
102
93
|
|
103
|
-
|
104
|
-
|
105
|
-
singleton_class.class_eval do
|
106
|
-
redefine_method(name) { val }
|
94
|
+
class_methods << <<~RUBY # In case the method exists and is not public
|
95
|
+
silence_redefinition_of_method def #{name}
|
107
96
|
end
|
97
|
+
RUBY
|
108
98
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if instance_variable_defined? ivar
|
113
|
-
instance_variable_get ivar
|
114
|
-
else
|
115
|
-
singleton_class.send name
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
99
|
+
methods << <<~RUBY if instance_reader
|
100
|
+
silence_redefinition_of_method def #{name}
|
101
|
+
defined?(@#{name}) ? @#{name} : self.class.#{name}
|
119
102
|
end
|
120
|
-
|
121
|
-
end
|
103
|
+
RUBY
|
122
104
|
|
123
|
-
|
124
|
-
|
125
|
-
if
|
126
|
-
|
127
|
-
|
128
|
-
self.class.public_send name
|
129
|
-
end
|
105
|
+
class_methods << <<~RUBY
|
106
|
+
silence_redefinition_of_method def #{name}=(value)
|
107
|
+
redefine_method(:#{name}) { value } if singleton_class?
|
108
|
+
redefine_singleton_method(:#{name}) { value }
|
109
|
+
value
|
130
110
|
end
|
111
|
+
RUBY
|
131
112
|
|
132
|
-
|
133
|
-
|
113
|
+
methods << <<~RUBY if instance_writer
|
114
|
+
silence_redefinition_of_method(:#{name}=)
|
115
|
+
attr_writer :#{name}
|
116
|
+
RUBY
|
134
117
|
|
135
|
-
if
|
136
|
-
|
137
|
-
|
118
|
+
if instance_predicate
|
119
|
+
class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
|
120
|
+
if instance_reader
|
121
|
+
methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
|
138
122
|
end
|
139
123
|
end
|
140
|
-
|
141
|
-
unless default_value.nil?
|
142
|
-
self.send("#{name}=", default_value)
|
143
|
-
end
|
144
124
|
end
|
125
|
+
|
126
|
+
location = caller_locations(1, 1).first
|
127
|
+
class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno)
|
128
|
+
|
129
|
+
attrs.each { |name| public_send("#{name}=", default) }
|
145
130
|
end
|
146
131
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
begin
|
5
|
-
# Test if this Ruby supports each_object against singleton_class
|
6
|
-
ObjectSpace.each_object(Numeric.singleton_class) {}
|
3
|
+
require "active_support/ruby_features"
|
7
4
|
|
5
|
+
class Class
|
6
|
+
if ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
|
8
7
|
# Returns an array with all classes that are < than its receiver.
|
9
8
|
#
|
10
9
|
# class C; end
|
@@ -19,21 +18,13 @@ class Class
|
|
19
18
|
# class D < C; end
|
20
19
|
# C.descendants # => [B, A, D]
|
21
20
|
def descendants
|
22
|
-
descendants
|
23
|
-
ObjectSpace.each_object(singleton_class) do |k|
|
24
|
-
next if k.singleton_class?
|
25
|
-
descendants.unshift k unless k == self
|
26
|
-
end
|
27
|
-
descendants
|
21
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
28
22
|
end
|
29
|
-
|
23
|
+
else
|
30
24
|
def descendants
|
31
|
-
|
32
|
-
|
33
|
-
descendants.unshift k if k < self
|
25
|
+
ObjectSpace.each_object(singleton_class).reject do |k|
|
26
|
+
k.singleton_class? || k == self
|
34
27
|
end
|
35
|
-
descendants.uniq!
|
36
|
-
descendants
|
37
28
|
end
|
38
29
|
end
|
39
30
|
|
@@ -45,10 +36,6 @@ class Class
|
|
45
36
|
#
|
46
37
|
# Foo.subclasses # => [Bar]
|
47
38
|
def subclasses
|
48
|
-
|
49
|
-
|
50
|
-
subclasses << k unless chain.any? { |c| c > k }
|
51
|
-
end
|
52
|
-
subclasses
|
53
|
-
end
|
39
|
+
descendants.select { |descendant| descendant.superclass == self }
|
40
|
+
end unless ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
|
54
41
|
end
|
@@ -13,22 +13,22 @@ class Date
|
|
13
13
|
class << self
|
14
14
|
attr_accessor :beginning_of_week_default
|
15
15
|
|
16
|
-
# Returns the week start (e.g.
|
16
|
+
# Returns the week start (e.g. +:monday+) for the current request, if this has been set (via Date.beginning_of_week=).
|
17
17
|
# If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
|
18
|
-
# If no config.beginning_of_week was specified, returns
|
18
|
+
# If no +config.beginning_of_week+ was specified, returns +:monday+.
|
19
19
|
def beginning_of_week
|
20
|
-
|
20
|
+
::ActiveSupport::IsolatedExecutionState[:beginning_of_week] || beginning_of_week_default || :monday
|
21
21
|
end
|
22
22
|
|
23
|
-
# Sets <tt>Date.beginning_of_week</tt> to a week start (e.g.
|
23
|
+
# Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. +:monday+) for current request/thread.
|
24
24
|
#
|
25
25
|
# This method accepts any of the following day symbols:
|
26
|
-
#
|
26
|
+
# +:monday+, +:tuesday+, +:wednesday+, +:thursday+, +:friday+, +:saturday+, +:sunday+
|
27
27
|
def beginning_of_week=(week_start)
|
28
|
-
|
28
|
+
::ActiveSupport::IsolatedExecutionState[:beginning_of_week] = find_beginning_of_week!(week_start)
|
29
29
|
end
|
30
30
|
|
31
|
-
# Returns week start day symbol (e.g.
|
31
|
+
# Returns week start day symbol (e.g. +:monday+), or raises an +ArgumentError+ for invalid day symbol.
|
32
32
|
def find_beginning_of_week!(week_start)
|
33
33
|
raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
|
34
34
|
week_start
|
@@ -87,7 +87,7 @@ class Date
|
|
87
87
|
end
|
88
88
|
alias :at_end_of_day :end_of_day
|
89
89
|
|
90
|
-
def plus_with_duration(other)
|
90
|
+
def plus_with_duration(other) # :nodoc:
|
91
91
|
if ActiveSupport::Duration === other
|
92
92
|
other.since(self)
|
93
93
|
else
|
@@ -97,7 +97,7 @@ class Date
|
|
97
97
|
alias_method :plus_without_duration, :+
|
98
98
|
alias_method :+, :plus_with_duration
|
99
99
|
|
100
|
-
def minus_with_duration(other)
|
100
|
+
def minus_with_duration(other) # :nodoc:
|
101
101
|
if ActiveSupport::Duration === other
|
102
102
|
plus_with_duration(-other)
|
103
103
|
else
|
@@ -110,12 +110,13 @@ class Date
|
|
110
110
|
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
|
111
111
|
# any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
|
112
112
|
def advance(options)
|
113
|
-
options = options.dup
|
114
113
|
d = self
|
115
|
-
|
116
|
-
d = d >> options
|
117
|
-
d = d
|
118
|
-
d = d +
|
114
|
+
|
115
|
+
d = d >> options[:years] * 12 if options[:years]
|
116
|
+
d = d >> options[:months] if options[:months]
|
117
|
+
d = d + options[:weeks] * 7 if options[:weeks]
|
118
|
+
d = d + options[:days] if options[:days]
|
119
|
+
|
119
120
|
d
|
120
121
|
end
|
121
122
|
|
@@ -10,6 +10,7 @@ class Date
|
|
10
10
|
short: "%d %b",
|
11
11
|
long: "%B %d, %Y",
|
12
12
|
db: "%Y-%m-%d",
|
13
|
+
inspect: "%Y-%m-%d",
|
13
14
|
number: "%Y%m%d",
|
14
15
|
long_ordinal: lambda { |date|
|
15
16
|
day_format = ActiveSupport::Inflector.ordinalize(date.day)
|
@@ -21,21 +22,21 @@ class Date
|
|
21
22
|
|
22
23
|
# Convert to a formatted string. See DATE_FORMATS for predefined formats.
|
23
24
|
#
|
24
|
-
# This method is aliased to <tt>
|
25
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
25
26
|
#
|
26
27
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
27
28
|
#
|
29
|
+
# date.to_fs(:db) # => "2007-11-10"
|
28
30
|
# date.to_formatted_s(:db) # => "2007-11-10"
|
29
|
-
# date.to_s(:db) # => "2007-11-10"
|
30
31
|
#
|
31
|
-
# date.
|
32
|
-
# date.
|
33
|
-
# date.
|
34
|
-
# date.
|
35
|
-
# date.
|
36
|
-
# date.
|
32
|
+
# date.to_fs(:short) # => "10 Nov"
|
33
|
+
# date.to_fs(:number) # => "20071110"
|
34
|
+
# date.to_fs(:long) # => "November 10, 2007"
|
35
|
+
# date.to_fs(:long_ordinal) # => "November 10th, 2007"
|
36
|
+
# date.to_fs(:rfc822) # => "10 Nov 2007"
|
37
|
+
# date.to_fs(:iso8601) # => "2007-11-10"
|
37
38
|
#
|
38
|
-
# == Adding your own date formats to
|
39
|
+
# == Adding your own date formats to to_fs
|
39
40
|
# You can add your own formats to the Date::DATE_FORMATS hash.
|
40
41
|
# Use the format name as the hash key and either a strftime string
|
41
42
|
# or Proc instance that takes a date argument as the value.
|
@@ -43,7 +44,7 @@ class Date
|
|
43
44
|
# # config/initializers/date_formats.rb
|
44
45
|
# Date::DATE_FORMATS[:month_and_year] = '%B %Y'
|
45
46
|
# Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
|
46
|
-
def
|
47
|
+
def to_fs(format = :default)
|
47
48
|
if formatter = DATE_FORMATS[format]
|
48
49
|
if formatter.respond_to?(:call)
|
49
50
|
formatter.call(self).to_s
|
@@ -54,8 +55,8 @@ class Date
|
|
54
55
|
to_default_s
|
55
56
|
end
|
56
57
|
end
|
58
|
+
alias_method :to_formatted_s, :to_fs
|
57
59
|
alias_method :to_default_s, :to_s
|
58
|
-
alias_method :to_s, :to_formatted_s
|
59
60
|
|
60
61
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
61
62
|
def readable_inspect
|
@@ -67,7 +68,7 @@ class Date
|
|
67
68
|
silence_redefinition_of_method :to_time
|
68
69
|
|
69
70
|
# Converts a Date instance to a Time, where the time is set to the beginning of the day.
|
70
|
-
# The timezone can be either
|
71
|
+
# The timezone can be either +:local+ or +:utc+ (default +:local+).
|
71
72
|
#
|
72
73
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
73
74
|
#
|
@@ -76,11 +77,11 @@ class Date
|
|
76
77
|
#
|
77
78
|
# date.to_time(:utc) # => 2007-11-10 00:00:00 UTC
|
78
79
|
#
|
79
|
-
# NOTE: The
|
80
|
-
#
|
80
|
+
# NOTE: The +:local+ timezone is Ruby's *process* timezone, i.e. <tt>ENV['TZ']</tt>.
|
81
|
+
# If the <b>application's</b> timezone is needed, then use +in_time_zone+ instead.
|
81
82
|
def to_time(form = :local)
|
82
83
|
raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form)
|
83
|
-
::Time.
|
84
|
+
::Time.public_send(form, year, month, day)
|
84
85
|
end
|
85
86
|
|
86
87
|
silence_redefinition_of_method :xmlschema
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
|
5
|
+
class Date
|
6
|
+
NOT_SET = Object.new # :nodoc:
|
7
|
+
def to_s(format = NOT_SET) # :nodoc:
|
8
|
+
if formatter = DATE_FORMATS[format]
|
9
|
+
ActiveSupport::Deprecation.warn(
|
10
|
+
"Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_fs(#{format.inspect}) instead."
|
11
|
+
)
|
12
|
+
if formatter.respond_to?(:call)
|
13
|
+
formatter.call(self).to_s
|
14
|
+
else
|
15
|
+
strftime(formatter)
|
16
|
+
end
|
17
|
+
elsif format == NOT_SET
|
18
|
+
to_default_s
|
19
|
+
else
|
20
|
+
ActiveSupport::Deprecation.warn(
|
21
|
+
"Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_fs(#{format.inspect}) instead."
|
22
|
+
)
|
23
|
+
to_default_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,4 +4,5 @@ require "active_support/core_ext/date/acts_like"
|
|
4
4
|
require "active_support/core_ext/date/blank"
|
5
5
|
require "active_support/core_ext/date/calculations"
|
6
6
|
require "active_support/core_ext/date/conversions"
|
7
|
+
require "active_support/core_ext/date/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
7
8
|
require "active_support/core_ext/date/zones"
|
@@ -1,17 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/try"
|
4
|
+
require "active_support/core_ext/date_time/conversions"
|
4
5
|
|
5
6
|
module DateAndTime
|
6
7
|
module Calculations
|
7
8
|
DAYS_INTO_WEEK = {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
sunday: 0,
|
10
|
+
monday: 1,
|
11
|
+
tuesday: 2,
|
12
|
+
wednesday: 3,
|
13
|
+
thursday: 4,
|
14
|
+
friday: 5,
|
15
|
+
saturday: 6
|
15
16
|
}
|
16
17
|
WEEKEND_DAYS = [ 6, 0 ]
|
17
18
|
|
@@ -20,26 +21,28 @@ module DateAndTime
|
|
20
21
|
advance(days: -1)
|
21
22
|
end
|
22
23
|
|
23
|
-
# Returns a new date/time the specified number of days ago.
|
24
|
-
def prev_day(days = 1)
|
25
|
-
advance(days: -days)
|
26
|
-
end
|
27
|
-
|
28
24
|
# Returns a new date/time representing tomorrow.
|
29
25
|
def tomorrow
|
30
26
|
advance(days: 1)
|
31
27
|
end
|
32
28
|
|
33
|
-
# Returns a new date/time the specified number of days in the future.
|
34
|
-
def next_day(days = 1)
|
35
|
-
advance(days: days)
|
36
|
-
end
|
37
|
-
|
38
29
|
# Returns true if the date/time is today.
|
39
30
|
def today?
|
40
31
|
to_date == ::Date.current
|
41
32
|
end
|
42
33
|
|
34
|
+
# Returns true if the date/time is tomorrow.
|
35
|
+
def tomorrow?
|
36
|
+
to_date == ::Date.current.tomorrow
|
37
|
+
end
|
38
|
+
alias :next_day? :tomorrow?
|
39
|
+
|
40
|
+
# Returns true if the date/time is yesterday.
|
41
|
+
def yesterday?
|
42
|
+
to_date == ::Date.current.yesterday
|
43
|
+
end
|
44
|
+
alias :prev_day? :yesterday?
|
45
|
+
|
43
46
|
# Returns true if the date/time is in the past.
|
44
47
|
def past?
|
45
48
|
self < self.class.current
|
@@ -60,6 +63,16 @@ module DateAndTime
|
|
60
63
|
!WEEKEND_DAYS.include?(wday)
|
61
64
|
end
|
62
65
|
|
66
|
+
# Returns true if the date/time falls before <tt>date_or_time</tt>.
|
67
|
+
def before?(date_or_time)
|
68
|
+
self < date_or_time
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns true if the date/time falls after <tt>date_or_time</tt>.
|
72
|
+
def after?(date_or_time)
|
73
|
+
self > date_or_time
|
74
|
+
end
|
75
|
+
|
63
76
|
# Returns a new date/time the specified number of days ago.
|
64
77
|
def days_ago(days)
|
65
78
|
advance(days: -days)
|
@@ -124,7 +137,7 @@ module DateAndTime
|
|
124
137
|
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
125
138
|
# now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
|
126
139
|
def beginning_of_quarter
|
127
|
-
first_quarter_month =
|
140
|
+
first_quarter_month = month - (2 + month) % 3
|
128
141
|
beginning_of_month.change(month: first_quarter_month)
|
129
142
|
end
|
130
143
|
alias :at_beginning_of_quarter :beginning_of_quarter
|
@@ -139,7 +152,7 @@ module DateAndTime
|
|
139
152
|
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
140
153
|
# now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
|
141
154
|
def end_of_quarter
|
142
|
-
last_quarter_month =
|
155
|
+
last_quarter_month = month + (12 - month) % 3
|
143
156
|
beginning_of_month.change(month: last_quarter_month).end_of_month
|
144
157
|
end
|
145
158
|
alias :at_end_of_quarter :end_of_quarter
|
@@ -188,21 +201,11 @@ module DateAndTime
|
|
188
201
|
end
|
189
202
|
end
|
190
203
|
|
191
|
-
#
|
192
|
-
def next_month(months = 1)
|
193
|
-
advance(months: months)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Short-hand for months_since(3)
|
204
|
+
# Short-hand for <tt>months_since(3)</tt>.
|
197
205
|
def next_quarter
|
198
206
|
months_since(3)
|
199
207
|
end
|
200
208
|
|
201
|
-
# Returns a new date/time the specified number of years in the future.
|
202
|
-
def next_year(years = 1)
|
203
|
-
advance(years: years)
|
204
|
-
end
|
205
|
-
|
206
209
|
# Returns a new date/time representing the given day in the previous week.
|
207
210
|
# Week is assumed to start on +start_day+, default is
|
208
211
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
@@ -223,28 +226,18 @@ module DateAndTime
|
|
223
226
|
end
|
224
227
|
alias_method :last_weekday, :prev_weekday
|
225
228
|
|
226
|
-
#
|
227
|
-
def prev_month(months = 1)
|
228
|
-
advance(months: -months)
|
229
|
-
end
|
230
|
-
|
231
|
-
# Short-hand for months_ago(1).
|
229
|
+
# Short-hand for <tt>months_ago(1)</tt>.
|
232
230
|
def last_month
|
233
231
|
months_ago(1)
|
234
232
|
end
|
235
233
|
|
236
|
-
# Short-hand for months_ago(3)
|
234
|
+
# Short-hand for <tt>months_ago(3)</tt>.
|
237
235
|
def prev_quarter
|
238
236
|
months_ago(3)
|
239
237
|
end
|
240
238
|
alias_method :last_quarter, :prev_quarter
|
241
239
|
|
242
|
-
#
|
243
|
-
def prev_year(years = 1)
|
244
|
-
advance(years: -years)
|
245
|
-
end
|
246
|
-
|
247
|
-
# Short-hand for years_ago(1).
|
240
|
+
# Short-hand for <tt>years_ago(1)</tt>.
|
248
241
|
def last_year
|
249
242
|
years_ago(1)
|
250
243
|
end
|
@@ -253,9 +246,8 @@ module DateAndTime
|
|
253
246
|
# Week is assumed to start on +start_day+, default is
|
254
247
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
255
248
|
def days_to_week_start(start_day = Date.beginning_of_week)
|
256
|
-
start_day_number = DAYS_INTO_WEEK
|
257
|
-
|
258
|
-
(current_day_number - start_day_number) % 7
|
249
|
+
start_day_number = DAYS_INTO_WEEK.fetch(start_day)
|
250
|
+
(wday - start_day_number) % 7
|
259
251
|
end
|
260
252
|
|
261
253
|
# Returns a new date/time representing the start of this week on the given day.
|
@@ -336,8 +328,7 @@ module DateAndTime
|
|
336
328
|
# today.next_occurring(:monday) # => Mon, 18 Dec 2017
|
337
329
|
# today.next_occurring(:thursday) # => Thu, 21 Dec 2017
|
338
330
|
def next_occurring(day_of_week)
|
339
|
-
|
340
|
-
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
|
331
|
+
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday
|
341
332
|
from_now += 7 unless from_now > 0
|
342
333
|
advance(days: from_now)
|
343
334
|
end
|
@@ -348,8 +339,7 @@ module DateAndTime
|
|
348
339
|
# today.prev_occurring(:monday) # => Mon, 11 Dec 2017
|
349
340
|
# today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
|
350
341
|
def prev_occurring(day_of_week)
|
351
|
-
|
352
|
-
ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
|
342
|
+
ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
|
353
343
|
ago += 7 unless ago > 0
|
354
344
|
advance(days: -ago)
|
355
345
|
end
|
@@ -364,7 +354,7 @@ module DateAndTime
|
|
364
354
|
end
|
365
355
|
|
366
356
|
def days_span(day)
|
367
|
-
(DAYS_INTO_WEEK
|
357
|
+
(DAYS_INTO_WEEK.fetch(day) - DAYS_INTO_WEEK.fetch(Date.beginning_of_week)) % 7
|
368
358
|
end
|
369
359
|
|
370
360
|
def copy_time_to(other)
|
@@ -12,5 +12,20 @@ module DateAndTime
|
|
12
12
|
# this behavior, but new apps will have an initializer that sets
|
13
13
|
# this to true, because the new behavior is preferred.
|
14
14
|
mattr_accessor :preserve_timezone, instance_writer: false, default: false
|
15
|
+
|
16
|
+
# Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
|
17
|
+
#
|
18
|
+
# When +true+, it returns local times with a UTC offset, with +false+ local
|
19
|
+
# times are returned as UTC.
|
20
|
+
#
|
21
|
+
# # Given this zone:
|
22
|
+
# zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
23
|
+
#
|
24
|
+
# # With `utc_to_local_returns_utc_offset_times = false`, local time is converted to UTC:
|
25
|
+
# zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 UTC
|
26
|
+
#
|
27
|
+
# # With `utc_to_local_returns_utc_offset_times = true`, local time is returned with UTC offset:
|
28
|
+
# zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 -0500
|
29
|
+
mattr_accessor :utc_to_local_returns_utc_offset_times, instance_writer: false, default: false
|
15
30
|
end
|
16
31
|
end
|
@@ -110,7 +110,7 @@ class DateTime
|
|
110
110
|
# instance time. Do not use this method in combination with x.months, use
|
111
111
|
# months_since instead!
|
112
112
|
def since(seconds)
|
113
|
-
self + Rational(seconds
|
113
|
+
self + Rational(seconds, 86400)
|
114
114
|
end
|
115
115
|
alias :in :since
|
116
116
|
|
@@ -9,21 +9,21 @@ require "active_support/values/time_zone"
|
|
9
9
|
class DateTime
|
10
10
|
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
11
11
|
#
|
12
|
-
# This method is aliased to <tt>
|
12
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
13
13
|
#
|
14
14
|
# === Examples
|
15
15
|
# datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
|
16
16
|
#
|
17
|
-
# datetime.
|
18
|
-
# datetime.
|
19
|
-
# datetime.
|
20
|
-
# datetime.
|
21
|
-
# datetime.
|
22
|
-
# datetime.
|
23
|
-
# datetime.
|
24
|
-
# datetime.
|
17
|
+
# datetime.to_fs(:db) # => "2007-12-04 00:00:00"
|
18
|
+
# datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
|
19
|
+
# datetime.to_fs(:number) # => "20071204000000"
|
20
|
+
# datetime.to_fs(:short) # => "04 Dec 00:00"
|
21
|
+
# datetime.to_fs(:long) # => "December 04, 2007 00:00"
|
22
|
+
# datetime.to_fs(:long_ordinal) # => "December 4th, 2007 00:00"
|
23
|
+
# datetime.to_fs(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
24
|
+
# datetime.to_fs(:iso8601) # => "2007-12-04T00:00:00+00:00"
|
25
25
|
#
|
26
|
-
# == Adding your own datetime formats to
|
26
|
+
# == Adding your own datetime formats to to_fs
|
27
27
|
# DateTime formats are shared with Time. You can add your own to the
|
28
28
|
# Time::DATE_FORMATS hash. Use the format name as the hash key and
|
29
29
|
# either a strftime string or Proc instance that takes a time or
|
@@ -32,15 +32,15 @@ class DateTime
|
|
32
32
|
# # config/initializers/time_formats.rb
|
33
33
|
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
34
34
|
# Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
|
35
|
-
def
|
35
|
+
def to_fs(format = :default)
|
36
36
|
if formatter = ::Time::DATE_FORMATS[format]
|
37
37
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
38
38
|
else
|
39
39
|
to_default_s
|
40
40
|
end
|
41
41
|
end
|
42
|
+
alias_method :to_formatted_s, :to_fs
|
42
43
|
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
43
|
-
alias_method :to_s, :to_formatted_s
|
44
44
|
|
45
45
|
# Returns a formatted string of the offset from UTC, or an alternative
|
46
46
|
# string if the time zone is already UTC.
|
@@ -54,7 +54,7 @@ class DateTime
|
|
54
54
|
|
55
55
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
|
56
56
|
def readable_inspect
|
57
|
-
|
57
|
+
to_fs(:rfc822)
|
58
58
|
end
|
59
59
|
alias_method :default_inspect, :inspect
|
60
60
|
alias_method :inspect, :readable_inspect
|
@@ -96,7 +96,6 @@ class DateTime
|
|
96
96
|
end
|
97
97
|
|
98
98
|
private
|
99
|
-
|
100
99
|
def offset_in_seconds
|
101
100
|
(offset * 86400).to_i
|
102
101
|
end
|