activesupport 6.0.6.1 → 7.1.3.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +865 -438
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -6
- data/lib/active_support/actionable_error.rb +4 -2
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +30 -10
- data/lib/active_support/benchmarkable.rb +4 -3
- data/lib/active_support/broadcast_logger.rb +250 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +53 -20
- data/lib/active_support/cache/mem_cache_store.rb +208 -63
- data/lib/active_support/cache/memory_store.rb +120 -38
- data/lib/active_support/cache/null_store.rb +16 -2
- data/lib/active_support/cache/redis_cache_store.rb +201 -208
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -66
- data/lib/active_support/cache.rb +539 -261
- data/lib/active_support/callbacks.rb +273 -142
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +53 -7
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +19 -6
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +15 -13
- 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/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 +34 -44
- data/lib/active_support/core_ext/class/subclasses.rb +19 -29
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +18 -16
- data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
- data/lib/active_support/core_ext/digest/uuid.rb +30 -13
- data/lib/active_support/core_ext/enumerable.rb +146 -72
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- 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_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +5 -5
- data/lib/active_support/core_ext/hash/slice.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- 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/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 +31 -29
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
- data/lib/active_support/core_ext/module/concerning.rb +14 -8
- data/lib/active_support/core_ext/module/delegation.rb +75 -42
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +1 -26
- data/lib/active_support/core_ext/name_error.rb +23 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +52 -28
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +25 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +6 -25
- data/lib/active_support/core_ext/range/conversions.rb +34 -13
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/regexp.rb +8 -1
- data/lib/active_support/core_ext/securerandom.rb +25 -13
- data/lib/active_support/core_ext/string/access.rb +5 -24
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +51 -10
- data/lib/active_support/core_ext/string/inquiry.rb +2 -1
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +85 -194
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
- 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/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +46 -8
- data/lib/active_support/core_ext/time/conversions.rb +16 -13
- data/lib/active_support/core_ext/time/zones.rb +12 -28
- 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 +54 -22
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- 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 +58 -769
- data/lib/active_support/deprecation/behaviors.rb +77 -38
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/instance_delegator.rb +31 -5
- data/lib/active_support/deprecation/method_wrappers.rb +12 -28
- data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
- data/lib/active_support/deprecation/reporting.rb +76 -16
- data/lib/active_support/deprecation.rb +36 -4
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +150 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +24 -12
- data/lib/active_support/duration.rb +136 -56
- data/lib/active_support/encrypted_configuration.rb +72 -9
- data/lib/active_support/encrypted_file.rb +46 -13
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +203 -0
- data/lib/active_support/evented_file_update_checker.rb +86 -137
- 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 +31 -12
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +79 -0
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +86 -42
- data/lib/active_support/html_safe_translation.rb +53 -0
- data/lib/active_support/i18n.rb +2 -1
- data/lib/active_support/i18n_railtie.rb +29 -27
- data/lib/active_support/inflector/inflections.rb +26 -9
- data/lib/active_support/inflector/methods.rb +54 -64
- data/lib/active_support/inflector/transliterate.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +6 -5
- data/lib/active_support/json/encoding.rb +31 -45
- data/lib/active_support/key_generator.rb +32 -7
- data/lib/active_support/lazy_load_hooks.rb +33 -7
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +101 -32
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_silence.rb +2 -26
- data/lib/active_support/logger_thread_safe_level.rb +24 -25
- data/lib/active_support/message_encryptor.rb +205 -58
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +237 -86
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +112 -46
- data/lib/active_support/messages/rotation_configuration.rb +2 -1
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +35 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +15 -52
- data/lib/active_support/multibyte/unicode.rb +8 -122
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +310 -105
- data/lib/active_support/notifications/instrumenter.rb +113 -48
- data/lib/active_support/notifications.rb +56 -29
- data/lib/active_support/number_helper/number_converter.rb +15 -8
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- 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 +5 -5
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
- data/lib/active_support/number_helper/rounding_helper.rb +12 -32
- data/lib/active_support/number_helper.rb +379 -304
- data/lib/active_support/option_merger.rb +11 -18
- data/lib/active_support/ordered_hash.rb +4 -4
- data/lib/active_support/ordered_options.rb +23 -3
- data/lib/active_support/parameter_filter.rb +104 -75
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +1 -4
- data/lib/active_support/railtie.rb +90 -6
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +18 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +19 -12
- data/lib/active_support/string_inquirer.rb +5 -3
- data/lib/active_support/subscriber.rb +23 -47
- data/lib/active_support/syntax_error_proxy.rb +70 -0
- data/lib/active_support/tagged_logging.rb +84 -23
- data/lib/active_support/test_case.rb +166 -27
- data/lib/active_support/testing/assertions.rb +73 -20
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +53 -2
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +24 -11
- 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 +16 -95
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/stream.rb +4 -6
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +89 -19
- data/lib/active_support/time_with_zone.rb +105 -70
- data/lib/active_support/values/time_zone.rb +59 -26
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +4 -11
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -5
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +9 -2
- data/lib/active_support/xml_mini.rb +7 -6
- data/lib/active_support.rb +40 -1
- metadata +127 -40
- 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/marshal.rb +0 -24
- 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
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/uri.rb +0 -25
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
- data/lib/active_support/per_thread_registry.rb +0 -60
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
# Test if this Ruby supports each_object against singleton_class
|
6
|
-
ObjectSpace.each_object(Numeric.singleton_class) { }
|
3
|
+
require "active_support/ruby_features"
|
4
|
+
require "active_support/descendants_tracker"
|
7
5
|
|
6
|
+
class Class
|
7
|
+
if ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
|
8
8
|
# Returns an array with all classes that are < than its receiver.
|
9
9
|
#
|
10
10
|
# class C; end
|
@@ -19,36 +19,26 @@ class Class
|
|
19
19
|
# class D < C; end
|
20
20
|
# C.descendants # => [B, A, D]
|
21
21
|
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
|
22
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
28
23
|
end
|
29
|
-
|
24
|
+
else
|
30
25
|
def descendants
|
31
|
-
|
32
|
-
|
33
|
-
descendants.unshift k if k < self
|
26
|
+
ObjectSpace.each_object(singleton_class).reject do |k|
|
27
|
+
k.singleton_class? || k == self
|
34
28
|
end
|
35
|
-
descendants.uniq!
|
36
|
-
descendants
|
37
29
|
end
|
38
|
-
end
|
39
30
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
chain.each do |k|
|
50
|
-
subclasses << k unless chain.any? { |c| c > k }
|
31
|
+
# Returns an array with the direct children of +self+.
|
32
|
+
#
|
33
|
+
# class Foo; end
|
34
|
+
# class Bar < Foo; end
|
35
|
+
# class Baz < Bar; end
|
36
|
+
#
|
37
|
+
# Foo.subclasses # => [Bar]
|
38
|
+
def subclasses
|
39
|
+
descendants.select { |descendant| descendant.superclass == self }
|
51
40
|
end
|
52
|
-
subclasses
|
53
41
|
end
|
42
|
+
|
43
|
+
prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
|
54
44
|
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
|
@@ -109,6 +109,21 @@ class Date
|
|
109
109
|
|
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
|
+
#
|
113
|
+
# The increments are applied in order of time units from largest to smallest.
|
114
|
+
# In other words, the date is incremented first by +:years+, then by
|
115
|
+
# +:months+, then by +:weeks+, then by +:days+. This order can affect the
|
116
|
+
# result around the end of a month. For example, incrementing first by months
|
117
|
+
# then by days:
|
118
|
+
#
|
119
|
+
# Date.new(2004, 9, 30).advance(months: 1, days: 1)
|
120
|
+
# # => Sun, 31 Oct 2004
|
121
|
+
#
|
122
|
+
# Whereas incrementing first by days then by months yields a different result:
|
123
|
+
#
|
124
|
+
# Date.new(2004, 9, 30).advance(days: 1).advance(months: 1)
|
125
|
+
# # => Mon, 01 Nov 2004
|
126
|
+
#
|
112
127
|
def advance(options)
|
113
128
|
d = self
|
114
129
|
|
@@ -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
|
@@ -51,11 +52,12 @@ class Date
|
|
51
52
|
strftime(formatter)
|
52
53
|
end
|
53
54
|
else
|
54
|
-
|
55
|
+
to_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
|
-
|
60
|
+
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
59
61
|
|
60
62
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
61
63
|
def readable_inspect
|
@@ -67,7 +69,7 @@ class Date
|
|
67
69
|
silence_redefinition_of_method :to_time
|
68
70
|
|
69
71
|
# Converts a Date instance to a Time, where the time is set to the beginning of the day.
|
70
|
-
# The timezone can be either
|
72
|
+
# The timezone can be either +:local+ or +:utc+ (default +:local+).
|
71
73
|
#
|
72
74
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
73
75
|
#
|
@@ -76,11 +78,11 @@ class Date
|
|
76
78
|
#
|
77
79
|
# date.to_time(:utc) # => 2007-11-10 00:00:00 UTC
|
78
80
|
#
|
79
|
-
# NOTE: The
|
80
|
-
#
|
81
|
+
# NOTE: The +:local+ timezone is Ruby's *process* timezone, i.e. <tt>ENV['TZ']</tt>.
|
82
|
+
# If the <b>application's</b> timezone is needed, then use +in_time_zone+ instead.
|
81
83
|
def to_time(form = :local)
|
82
84
|
raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form)
|
83
|
-
::Time.
|
85
|
+
::Time.public_send(form, year, month, day)
|
84
86
|
end
|
85
87
|
|
86
88
|
silence_redefinition_of_method :xmlschema
|
@@ -1,6 +1,7 @@
|
|
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
|
@@ -30,6 +31,18 @@ module DateAndTime
|
|
30
31
|
to_date == ::Date.current
|
31
32
|
end
|
32
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
|
+
|
33
46
|
# Returns true if the date/time is in the past.
|
34
47
|
def past?
|
35
48
|
self < self.class.current
|
@@ -144,6 +157,16 @@ module DateAndTime
|
|
144
157
|
end
|
145
158
|
alias :at_end_of_quarter :end_of_quarter
|
146
159
|
|
160
|
+
# Returns the quarter for a date/time.
|
161
|
+
#
|
162
|
+
# Date.new(2010, 1, 31).quarter # => 1
|
163
|
+
# Date.new(2010, 4, 12).quarter # => 2
|
164
|
+
# Date.new(2010, 9, 15).quarter # => 3
|
165
|
+
# Date.new(2010, 12, 25).quarter # => 4
|
166
|
+
def quarter
|
167
|
+
(month / 3.0).ceil
|
168
|
+
end
|
169
|
+
|
147
170
|
# Returns a new date/time at the beginning of the year.
|
148
171
|
#
|
149
172
|
# today = Date.today # => Fri, 10 Jul 2015
|
@@ -188,7 +211,7 @@ module DateAndTime
|
|
188
211
|
end
|
189
212
|
end
|
190
213
|
|
191
|
-
# Short-hand for months_since(3)
|
214
|
+
# Short-hand for <tt>months_since(3)</tt>.
|
192
215
|
def next_quarter
|
193
216
|
months_since(3)
|
194
217
|
end
|
@@ -213,18 +236,18 @@ module DateAndTime
|
|
213
236
|
end
|
214
237
|
alias_method :last_weekday, :prev_weekday
|
215
238
|
|
216
|
-
# Short-hand for months_ago(1)
|
239
|
+
# Short-hand for <tt>months_ago(1)</tt>.
|
217
240
|
def last_month
|
218
241
|
months_ago(1)
|
219
242
|
end
|
220
243
|
|
221
|
-
# Short-hand for months_ago(3)
|
244
|
+
# Short-hand for <tt>months_ago(3)</tt>.
|
222
245
|
def prev_quarter
|
223
246
|
months_ago(3)
|
224
247
|
end
|
225
248
|
alias_method :last_quarter, :prev_quarter
|
226
249
|
|
227
|
-
# Short-hand for years_ago(1)
|
250
|
+
# Short-hand for <tt>years_ago(1)</tt>.
|
228
251
|
def last_year
|
229
252
|
years_ago(1)
|
230
253
|
end
|
@@ -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
|
@@ -75,6 +75,10 @@ class DateTime
|
|
75
75
|
# The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
|
76
76
|
# <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
|
77
77
|
# <tt>:minutes</tt>, <tt>:seconds</tt>.
|
78
|
+
#
|
79
|
+
# Just like Date#advance, increments are applied in order of time units from
|
80
|
+
# largest to smallest. This order can affect the result around the end of a
|
81
|
+
# month.
|
78
82
|
def advance(options)
|
79
83
|
unless options[:weeks].nil?
|
80
84
|
options[:weeks], partial_weeks = options[:weeks].divmod(1)
|
@@ -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,19 @@ 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_s
|
40
40
|
end
|
41
41
|
end
|
42
|
-
alias_method :
|
43
|
-
|
42
|
+
alias_method :to_formatted_s, :to_fs
|
43
|
+
if instance_methods(false).include?(:to_s)
|
44
|
+
alias_method :to_default_s, :to_s
|
45
|
+
deprecate to_default_s: :to_s, deprecator: ActiveSupport.deprecator
|
46
|
+
end
|
47
|
+
|
44
48
|
|
45
49
|
# Returns a formatted string of the offset from UTC, or an alternative
|
46
50
|
# string if the time zone is already UTC.
|
@@ -54,7 +58,7 @@ class DateTime
|
|
54
58
|
|
55
59
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
|
56
60
|
def readable_inspect
|
57
|
-
|
61
|
+
to_fs(:rfc822)
|
58
62
|
end
|
59
63
|
alias_method :default_inspect, :inspect
|
60
64
|
alias_method :inspect, :readable_inspect
|
@@ -1,29 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "securerandom"
|
4
|
+
require "openssl"
|
4
5
|
|
5
6
|
module Digest
|
6
7
|
module UUID
|
7
|
-
DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8"
|
8
|
-
URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8"
|
9
|
-
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8"
|
10
|
-
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8"
|
8
|
+
DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
9
|
+
URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
10
|
+
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
11
|
+
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
11
12
|
|
12
13
|
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
13
14
|
#
|
14
|
-
# Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
|
15
|
+
# Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs.
|
15
16
|
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
16
17
|
#
|
17
18
|
# See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
|
18
|
-
def self.uuid_from_hash(hash_class,
|
19
|
-
if hash_class == Digest::MD5
|
19
|
+
def self.uuid_from_hash(hash_class, namespace, name)
|
20
|
+
if hash_class == Digest::MD5 || hash_class == OpenSSL::Digest::MD5
|
20
21
|
version = 3
|
21
|
-
elsif hash_class == Digest::SHA1
|
22
|
+
elsif hash_class == Digest::SHA1 || hash_class == OpenSSL::Digest::SHA1
|
22
23
|
version = 5
|
23
24
|
else
|
24
|
-
raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
|
25
|
+
raise ArgumentError, "Expected OpenSSL::Digest::SHA1 or OpenSSL::Digest::MD5, got #{hash_class.name}."
|
25
26
|
end
|
26
27
|
|
28
|
+
uuid_namespace = pack_uuid_namespace(namespace)
|
29
|
+
|
27
30
|
hash = hash_class.new
|
28
31
|
hash.update(uuid_namespace)
|
29
32
|
hash.update(name)
|
@@ -35,19 +38,33 @@ module Digest
|
|
35
38
|
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
36
39
|
end
|
37
40
|
|
38
|
-
# Convenience method for uuid_from_hash using Digest::MD5.
|
41
|
+
# Convenience method for uuid_from_hash using OpenSSL::Digest::MD5.
|
39
42
|
def self.uuid_v3(uuid_namespace, name)
|
40
|
-
uuid_from_hash(Digest::MD5, uuid_namespace, name)
|
43
|
+
uuid_from_hash(OpenSSL::Digest::MD5, uuid_namespace, name)
|
41
44
|
end
|
42
45
|
|
43
|
-
# Convenience method for uuid_from_hash using Digest::SHA1.
|
46
|
+
# Convenience method for uuid_from_hash using OpenSSL::Digest::SHA1.
|
44
47
|
def self.uuid_v5(uuid_namespace, name)
|
45
|
-
uuid_from_hash(Digest::SHA1, uuid_namespace, name)
|
48
|
+
uuid_from_hash(OpenSSL::Digest::SHA1, uuid_namespace, name)
|
46
49
|
end
|
47
50
|
|
48
51
|
# Convenience method for SecureRandom.uuid.
|
49
52
|
def self.uuid_v4
|
50
53
|
SecureRandom.uuid
|
51
54
|
end
|
55
|
+
|
56
|
+
def self.pack_uuid_namespace(namespace)
|
57
|
+
if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace)
|
58
|
+
namespace
|
59
|
+
else
|
60
|
+
match_data = namespace.match(/\A(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})\z/)
|
61
|
+
|
62
|
+
raise ArgumentError, "Only UUIDs are valid namespace identifiers" unless match_data.present?
|
63
|
+
|
64
|
+
match_data.captures.map { |s| s.to_i(16) }.pack("NnnnnN")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private_class_method :pack_uuid_namespace
|
52
69
|
end
|
53
70
|
end
|