activesupport 4.0.12 → 7.0.2.4
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 +5 -5
- data/CHANGELOG.md +249 -501
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +41 -13
- data/lib/active_support/benchmarkable.rb +7 -15
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +96 -74
- data/lib/active_support/cache/mem_cache_store.rb +211 -103
- data/lib/active_support/cache/memory_store.rb +90 -58
- data/lib/active_support/cache/null_store.rb +19 -7
- data/lib/active_support/cache/redis_cache_store.rb +468 -0
- data/lib/active_support/cache/strategy/local_cache.rb +86 -83
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +580 -241
- data/lib/active_support/callbacks.rb +812 -425
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +103 -14
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +21 -19
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +47 -1
- data/lib/active_support/core_ext/array/conversions.rb +35 -44
- 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/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +26 -16
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +10 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +25 -26
- data/lib/active_support/core_ext/class.rb +4 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +31 -18
- data/lib/active_support/core_ext/date/conversions.rb +43 -32
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +7 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +8 -4
- data/lib/active_support/core_ext/digest/uuid.rb +79 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +249 -17
- data/lib/active_support/core_ext/file/atomic.rb +41 -32
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +14 -5
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +39 -56
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -23
- data/lib/active_support/core_ext/hash.rb +10 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +172 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +23 -38
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -10
- data/lib/active_support/core_ext/name_error.rb +45 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +70 -20
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +17 -47
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +244 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +106 -26
- data/lib/active_support/core_ext/object/with_options.rb +64 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- 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 +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +10 -1
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +42 -51
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +18 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +97 -7
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +106 -25
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +18 -9
- data/lib/active_support/core_ext/string/output_safety.rb +227 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- 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/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +178 -116
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +37 -25
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +44 -42
- data/lib/active_support/core_ext/time.rb +8 -5
- data/lib/active_support/core_ext/uri.rb +4 -25
- data/lib/active_support/core_ext.rb +4 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +49 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +71 -696
- data/lib/active_support/deprecation/behaviors.rb +65 -16
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +62 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
- data/lib/active_support/deprecation/reporting.rb +81 -18
- data/lib/active_support/deprecation.rb +19 -11
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +67 -0
- data/lib/active_support/duration.rb +437 -39
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- 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 +170 -0
- 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 +151 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +207 -54
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +10 -6
- data/lib/active_support/i18n_railtie.rb +48 -19
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +97 -37
- data/lib/active_support/inflector/methods.rb +192 -157
- data/lib/active_support/inflector/transliterate.rb +83 -33
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +64 -0
- data/lib/active_support/json/decoding.rb +37 -42
- data/lib/active_support/json/encoding.rb +93 -293
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +30 -47
- data/lib/active_support/lazy_load_hooks.rb +54 -21
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +61 -18
- data/lib/active_support/logger.rb +40 -4
- data/lib/active_support/logger_silence.rb +17 -20
- data/lib/active_support/logger_thread_safe_level.rb +69 -0
- data/lib/active_support/message_encryptor.rb +178 -55
- data/lib/active_support/message_verifier.rb +195 -26
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +45 -92
- data/lib/active_support/multibyte/unicode.rb +44 -377
- data/lib/active_support/multibyte.rb +5 -3
- data/lib/active_support/notifications/fanout.rb +177 -44
- data/lib/active_support/notifications/instrumenter.rb +117 -17
- data/lib/active_support/notifications.rb +106 -39
- data/lib/active_support/number_helper/number_converter.rb +181 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +152 -394
- data/lib/active_support/option_merger.rb +18 -5
- data/lib/active_support/ordered_hash.rb +8 -6
- data/lib/active_support/ordered_options.rb +43 -7
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +24 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -11
- data/lib/active_support/railtie.rb +118 -12
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +112 -57
- 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 +38 -0
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +109 -39
- data/lib/active_support/tagged_logging.rb +54 -17
- data/lib/active_support/test_case.rb +121 -37
- data/lib/active_support/testing/assertions.rb +177 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +65 -11
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +56 -87
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- 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/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +6 -4
- data/lib/active_support/testing/time_helpers.rb +246 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +315 -90
- data/lib/active_support/values/time_zone.rb +306 -135
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +117 -115
- data/lib/active_support/xml_mini/libxml.rb +22 -21
- data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
- data/lib/active_support/xml_mini/nokogiri.rb +19 -19
- data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
- data/lib/active_support/xml_mini/rexml.rb +25 -17
- data/lib/active_support/xml_mini.rb +67 -56
- data/lib/active_support.rb +58 -3
- metadata +125 -66
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/marshal.rb +0 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/duration"
|
4
|
+
require "active_support/core_ext/time/conversions"
|
5
|
+
require "active_support/time_with_zone"
|
6
|
+
require "active_support/core_ext/time/zones"
|
7
|
+
require "active_support/core_ext/date_and_time/calculations"
|
8
|
+
require "active_support/core_ext/date/calculations"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
7
10
|
|
8
11
|
class Time
|
9
12
|
include DateAndTime::Calculations
|
@@ -16,9 +19,9 @@ class Time
|
|
16
19
|
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
|
17
20
|
end
|
18
21
|
|
19
|
-
#
|
22
|
+
# Returns the number of days in the given month.
|
20
23
|
# If no year is specified, it will use the current year.
|
21
|
-
def days_in_month(month, year =
|
24
|
+
def days_in_month(month, year = current.year)
|
22
25
|
if month == 2 && ::Date.gregorian_leap?(year)
|
23
26
|
29
|
24
27
|
else
|
@@ -26,39 +29,10 @@ class Time
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
# otherwise returns a DateTime.
|
34
|
-
def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
|
35
|
-
ActiveSupport::Deprecation.warn 'time_with_datetime_fallback is deprecated. Use Time#utc or Time#local instead', caller
|
36
|
-
time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
|
37
|
-
|
38
|
-
# This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
|
39
|
-
if time.year == year
|
40
|
-
time
|
41
|
-
else
|
42
|
-
::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
|
43
|
-
end
|
44
|
-
rescue
|
45
|
-
::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
|
46
|
-
end
|
47
|
-
|
48
|
-
# *DEPRECATED*: Use +Time#utc+ instead.
|
49
|
-
#
|
50
|
-
# Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
|
51
|
-
def utc_time(*args)
|
52
|
-
ActiveSupport::Deprecation.warn 'utc_time is deprecated. Use Time#utc instead', caller
|
53
|
-
time_with_datetime_fallback(:utc, *args)
|
54
|
-
end
|
55
|
-
|
56
|
-
# *DEPRECATED*: Use +Time#local+ instead.
|
57
|
-
#
|
58
|
-
# Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
|
59
|
-
def local_time(*args)
|
60
|
-
ActiveSupport::Deprecation.warn 'local_time is deprecated. Use Time#local instead', caller
|
61
|
-
time_with_datetime_fallback(:local, *args)
|
32
|
+
# Returns the number of days in the given year.
|
33
|
+
# If no year is specified, it will use the current year.
|
34
|
+
def days_in_year(year = current.year)
|
35
|
+
days_in_month(2, year) + 337
|
62
36
|
end
|
63
37
|
|
64
38
|
# Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
|
@@ -68,13 +42,15 @@ class Time
|
|
68
42
|
|
69
43
|
# Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
|
70
44
|
# instances can be used when called with a single argument
|
71
|
-
def at_with_coercion(*args)
|
72
|
-
return at_without_coercion(*args) if args.size != 1
|
45
|
+
def at_with_coercion(*args, **kwargs)
|
46
|
+
return at_without_coercion(*args, **kwargs) if args.size != 1 || !kwargs.empty?
|
73
47
|
|
74
48
|
# Time.at can be called with a time or numerical value
|
75
49
|
time_or_number = args.first
|
76
50
|
|
77
|
-
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
51
|
+
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
52
|
+
at_without_coercion(time_or_number.to_r).getlocal
|
53
|
+
elsif time_or_number.is_a?(DateTime)
|
78
54
|
at_without_coercion(time_or_number.to_f).getlocal
|
79
55
|
else
|
80
56
|
at_without_coercion(time_or_number)
|
@@ -82,11 +58,38 @@ class Time
|
|
82
58
|
end
|
83
59
|
alias_method :at_without_coercion, :at
|
84
60
|
alias_method :at, :at_with_coercion
|
61
|
+
|
62
|
+
# Creates a +Time+ instance from an RFC 3339 string.
|
63
|
+
#
|
64
|
+
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
65
|
+
#
|
66
|
+
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
67
|
+
#
|
68
|
+
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
69
|
+
def rfc3339(str)
|
70
|
+
parts = Date._rfc3339(str)
|
71
|
+
|
72
|
+
raise ArgumentError, "invalid date" if parts.empty?
|
73
|
+
|
74
|
+
Time.new(
|
75
|
+
parts.fetch(:year),
|
76
|
+
parts.fetch(:mon),
|
77
|
+
parts.fetch(:mday),
|
78
|
+
parts.fetch(:hour),
|
79
|
+
parts.fetch(:min),
|
80
|
+
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
81
|
+
parts.fetch(:offset)
|
82
|
+
)
|
83
|
+
end
|
85
84
|
end
|
86
85
|
|
87
|
-
#
|
86
|
+
# Returns the number of seconds since 00:00:00.
|
87
|
+
#
|
88
|
+
# Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
|
89
|
+
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
90
|
+
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
88
91
|
def seconds_since_midnight
|
89
|
-
to_i - change(:
|
92
|
+
to_i - change(hour: 0).to_i + (usec / 1.0e+6)
|
90
93
|
end
|
91
94
|
|
92
95
|
# Returns the number of seconds until 23:59:59.
|
@@ -98,39 +101,84 @@ class Time
|
|
98
101
|
end_of_day.to_i - to_i
|
99
102
|
end
|
100
103
|
|
104
|
+
# Returns the fraction of a second as a +Rational+
|
105
|
+
#
|
106
|
+
# Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
|
107
|
+
def sec_fraction
|
108
|
+
subsec
|
109
|
+
end
|
110
|
+
|
111
|
+
unless Time.method_defined?(:floor)
|
112
|
+
def floor(precision = 0)
|
113
|
+
change(nsec: 0) + subsec.floor(precision)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
118
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
119
|
+
if RUBY_VERSION <= "2.8"
|
120
|
+
remove_possible_method :ceil
|
121
|
+
def ceil(precision = 0)
|
122
|
+
change(nsec: 0) + subsec.ceil(precision)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
101
126
|
# Returns a new Time where one or more of the elements have been changed according
|
102
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
103
|
-
# <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only
|
104
|
-
# then minute, sec, and
|
105
|
-
# sec and
|
106
|
-
# keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
107
|
-
# <tt>:sec</tt>, <tt>:usec</tt
|
128
|
+
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
129
|
+
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
130
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
131
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
132
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
133
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
108
134
|
#
|
109
135
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
110
136
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
111
137
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
112
138
|
def change(options)
|
113
|
-
new_year
|
114
|
-
new_month
|
115
|
-
new_day
|
116
|
-
new_hour
|
117
|
-
new_min
|
118
|
-
new_sec
|
119
|
-
|
120
|
-
|
121
|
-
if
|
122
|
-
|
139
|
+
new_year = options.fetch(:year, year)
|
140
|
+
new_month = options.fetch(:month, month)
|
141
|
+
new_day = options.fetch(:day, day)
|
142
|
+
new_hour = options.fetch(:hour, hour)
|
143
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
144
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
145
|
+
new_offset = options.fetch(:offset, nil)
|
146
|
+
|
147
|
+
if new_nsec = options[:nsec]
|
148
|
+
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
149
|
+
new_usec = Rational(new_nsec, 1000)
|
150
|
+
else
|
151
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
152
|
+
end
|
153
|
+
|
154
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
155
|
+
|
156
|
+
new_sec += Rational(new_usec, 1000000)
|
157
|
+
|
158
|
+
if new_offset
|
159
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
160
|
+
elsif utc?
|
161
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
162
|
+
elsif zone&.respond_to?(:utc_to_local)
|
163
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
|
123
164
|
elsif zone
|
124
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
165
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
125
166
|
else
|
126
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec
|
167
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
127
168
|
end
|
128
169
|
end
|
129
170
|
|
130
|
-
# Uses Date to provide precise Time calculations for years, months, and days
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# <tt>:
|
171
|
+
# Uses Date to provide precise Time calculations for years, months, and days
|
172
|
+
# according to the proleptic Gregorian calendar. The +options+ parameter
|
173
|
+
# takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
|
174
|
+
# <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
|
175
|
+
# <tt>:seconds</tt>.
|
176
|
+
#
|
177
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
|
178
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
|
179
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
|
180
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
|
181
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
|
134
182
|
def advance(options)
|
135
183
|
unless options[:weeks].nil?
|
136
184
|
options[:weeks], partial_weeks = options[:weeks].divmod(1)
|
@@ -142,8 +190,8 @@ class Time
|
|
142
190
|
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
143
191
|
end
|
144
192
|
|
145
|
-
d = to_date.advance(options)
|
146
|
-
time_advanced_by_date = change(:
|
193
|
+
d = to_date.gregorian.advance(options)
|
194
|
+
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
147
195
|
seconds_to_advance = \
|
148
196
|
options.fetch(:seconds, 0) +
|
149
197
|
options.fetch(:minutes, 0) * 60 +
|
@@ -171,82 +219,65 @@ class Time
|
|
171
219
|
|
172
220
|
# Returns a new Time representing the start of the day (0:00)
|
173
221
|
def beginning_of_day
|
174
|
-
|
175
|
-
change(:hour => 0)
|
222
|
+
change(hour: 0)
|
176
223
|
end
|
177
224
|
alias :midnight :beginning_of_day
|
178
225
|
alias :at_midnight :beginning_of_day
|
179
226
|
alias :at_beginning_of_day :beginning_of_day
|
180
227
|
|
181
|
-
# Returns a new Time representing the
|
228
|
+
# Returns a new Time representing the middle of the day (12:00)
|
229
|
+
def middle_of_day
|
230
|
+
change(hour: 12)
|
231
|
+
end
|
232
|
+
alias :midday :middle_of_day
|
233
|
+
alias :noon :middle_of_day
|
234
|
+
alias :at_midday :middle_of_day
|
235
|
+
alias :at_noon :middle_of_day
|
236
|
+
alias :at_middle_of_day :middle_of_day
|
237
|
+
|
238
|
+
# Returns a new Time representing the end of the day, 23:59:59.999999
|
182
239
|
def end_of_day
|
183
240
|
change(
|
184
|
-
:
|
185
|
-
:
|
186
|
-
:
|
187
|
-
:
|
241
|
+
hour: 23,
|
242
|
+
min: 59,
|
243
|
+
sec: 59,
|
244
|
+
usec: Rational(999999999, 1000)
|
188
245
|
)
|
189
246
|
end
|
190
247
|
alias :at_end_of_day :end_of_day
|
191
248
|
|
192
249
|
# Returns a new Time representing the start of the hour (x:00)
|
193
250
|
def beginning_of_hour
|
194
|
-
change(:
|
251
|
+
change(min: 0)
|
195
252
|
end
|
196
253
|
alias :at_beginning_of_hour :beginning_of_hour
|
197
254
|
|
198
|
-
# Returns a new Time representing the end of the hour, x:59:59.999999
|
255
|
+
# Returns a new Time representing the end of the hour, x:59:59.999999
|
199
256
|
def end_of_hour
|
200
257
|
change(
|
201
|
-
:
|
202
|
-
:
|
203
|
-
:
|
258
|
+
min: 59,
|
259
|
+
sec: 59,
|
260
|
+
usec: Rational(999999999, 1000)
|
204
261
|
)
|
205
262
|
end
|
206
263
|
alias :at_end_of_hour :end_of_hour
|
207
264
|
|
208
265
|
# Returns a new Time representing the start of the minute (x:xx:00)
|
209
266
|
def beginning_of_minute
|
210
|
-
change(:
|
267
|
+
change(sec: 0)
|
211
268
|
end
|
212
269
|
alias :at_beginning_of_minute :beginning_of_minute
|
213
270
|
|
214
|
-
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
271
|
+
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
215
272
|
def end_of_minute
|
216
273
|
change(
|
217
|
-
:
|
218
|
-
:
|
274
|
+
sec: 59,
|
275
|
+
usec: Rational(999999999, 1000)
|
219
276
|
)
|
220
277
|
end
|
221
278
|
alias :at_end_of_minute :end_of_minute
|
222
279
|
|
223
|
-
|
224
|
-
def all_day
|
225
|
-
beginning_of_day..end_of_day
|
226
|
-
end
|
227
|
-
|
228
|
-
# Returns a Range representing the whole week of the current time.
|
229
|
-
# Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
|
230
|
-
def all_week(start_day = Date.beginning_of_week)
|
231
|
-
beginning_of_week(start_day)..end_of_week(start_day)
|
232
|
-
end
|
233
|
-
|
234
|
-
# Returns a Range representing the whole month of the current time.
|
235
|
-
def all_month
|
236
|
-
beginning_of_month..end_of_month
|
237
|
-
end
|
238
|
-
|
239
|
-
# Returns a Range representing the whole quarter of the current time.
|
240
|
-
def all_quarter
|
241
|
-
beginning_of_quarter..end_of_quarter
|
242
|
-
end
|
243
|
-
|
244
|
-
# Returns a Range representing the whole year of the current time.
|
245
|
-
def all_year
|
246
|
-
beginning_of_year..end_of_year
|
247
|
-
end
|
248
|
-
|
249
|
-
def plus_with_duration(other) #:nodoc:
|
280
|
+
def plus_with_duration(other) # :nodoc:
|
250
281
|
if ActiveSupport::Duration === other
|
251
282
|
other.since(self)
|
252
283
|
else
|
@@ -256,7 +287,7 @@ class Time
|
|
256
287
|
alias_method :plus_without_duration, :+
|
257
288
|
alias_method :+, :plus_with_duration
|
258
289
|
|
259
|
-
def minus_with_duration(other)
|
290
|
+
def minus_with_duration(other) # :nodoc:
|
260
291
|
if ActiveSupport::Duration === other
|
261
292
|
other.until(self)
|
262
293
|
else
|
@@ -274,13 +305,15 @@ class Time
|
|
274
305
|
other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
|
275
306
|
end
|
276
307
|
alias_method :minus_without_coercion, :-
|
277
|
-
alias_method :-, :minus_with_coercion
|
308
|
+
alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
|
278
309
|
|
279
310
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
280
311
|
# can be chronologically compared with a Time
|
281
312
|
def compare_with_coercion(other)
|
282
|
-
# we're avoiding Time#to_datetime
|
283
|
-
if other.
|
313
|
+
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
|
314
|
+
if other.class == Time
|
315
|
+
compare_without_coercion(other)
|
316
|
+
elsif other.is_a?(Time)
|
284
317
|
compare_without_coercion(other.to_time)
|
285
318
|
else
|
286
319
|
to_datetime <=> other
|
@@ -299,4 +332,33 @@ class Time
|
|
299
332
|
alias_method :eql_without_coercion, :eql?
|
300
333
|
alias_method :eql?, :eql_with_coercion
|
301
334
|
|
335
|
+
# Returns a new time the specified number of days ago.
|
336
|
+
def prev_day(days = 1)
|
337
|
+
advance(days: -days)
|
338
|
+
end
|
339
|
+
|
340
|
+
# Returns a new time the specified number of days in the future.
|
341
|
+
def next_day(days = 1)
|
342
|
+
advance(days: days)
|
343
|
+
end
|
344
|
+
|
345
|
+
# Returns a new time the specified number of months ago.
|
346
|
+
def prev_month(months = 1)
|
347
|
+
advance(months: -months)
|
348
|
+
end
|
349
|
+
|
350
|
+
# Returns a new time the specified number of months in the future.
|
351
|
+
def next_month(months = 1)
|
352
|
+
advance(months: months)
|
353
|
+
end
|
354
|
+
|
355
|
+
# Returns a new time the specified number of years ago.
|
356
|
+
def prev_year(years = 1)
|
357
|
+
advance(years: -years)
|
358
|
+
end
|
359
|
+
|
360
|
+
# Returns a new time the specified number of years in the future.
|
361
|
+
def next_year(years = 1)
|
362
|
+
advance(years: years)
|
363
|
+
end
|
302
364
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/date_and_time/compatibility"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
5
|
+
|
6
|
+
class Time
|
7
|
+
include DateAndTime::Compatibility
|
8
|
+
|
9
|
+
silence_redefinition_of_method :to_time
|
10
|
+
|
11
|
+
# Either return +self+ or the time in the local system timezone depending
|
12
|
+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
13
|
+
def to_time
|
14
|
+
preserve_timezone ? self : getlocal
|
15
|
+
end
|
16
|
+
end
|
@@ -1,41 +1,48 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
require "active_support/inflector/methods"
|
5
|
+
require "active_support/values/time_zone"
|
3
6
|
|
4
7
|
class Time
|
5
8
|
DATE_FORMATS = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
9
|
+
db: "%Y-%m-%d %H:%M:%S",
|
10
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
11
|
+
number: "%Y%m%d%H%M%S",
|
12
|
+
nsec: "%Y%m%d%H%M%S%9N",
|
13
|
+
usec: "%Y%m%d%H%M%S%6N",
|
14
|
+
time: "%H:%M",
|
15
|
+
short: "%d %b %H:%M",
|
16
|
+
long: "%B %d, %Y %H:%M",
|
17
|
+
long_ordinal: lambda { |time|
|
13
18
|
day_format = ActiveSupport::Inflector.ordinalize(time.day)
|
14
19
|
time.strftime("%B #{day_format}, %Y %H:%M")
|
15
20
|
},
|
16
|
-
:
|
21
|
+
rfc822: lambda { |time|
|
17
22
|
offset_format = time.formatted_offset(false)
|
18
23
|
time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
|
19
|
-
}
|
24
|
+
},
|
25
|
+
iso8601: lambda { |time| time.iso8601 }
|
20
26
|
}
|
21
27
|
|
22
|
-
# Converts to a formatted string. See DATE_FORMATS for
|
28
|
+
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
23
29
|
#
|
24
|
-
# This method is aliased to <tt>
|
30
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
25
31
|
#
|
26
|
-
# time = Time.now # =>
|
32
|
+
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
27
33
|
#
|
34
|
+
# time.to_fs(:time) # => "06:10"
|
28
35
|
# time.to_formatted_s(:time) # => "06:10"
|
29
|
-
# time.to_s(:time) # => "06:10"
|
30
36
|
#
|
31
|
-
# time.
|
32
|
-
# time.
|
33
|
-
# time.
|
34
|
-
# time.
|
35
|
-
# time.
|
36
|
-
# time.
|
37
|
+
# time.to_fs(:db) # => "2007-01-18 06:10:17"
|
38
|
+
# time.to_fs(:number) # => "20070118061017"
|
39
|
+
# time.to_fs(:short) # => "18 Jan 06:10"
|
40
|
+
# time.to_fs(:long) # => "January 18, 2007 06:10"
|
41
|
+
# time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
|
42
|
+
# time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
|
43
|
+
# time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
|
37
44
|
#
|
38
|
-
# == Adding your own time formats to +
|
45
|
+
# == Adding your own time formats to +to_fs+
|
39
46
|
# You can add your own formats to the Time::DATE_FORMATS hash.
|
40
47
|
# Use the format name as the hash key and either a strftime string
|
41
48
|
# or Proc instance that takes a time argument as the value.
|
@@ -43,21 +50,26 @@ class Time
|
|
43
50
|
# # config/initializers/time_formats.rb
|
44
51
|
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
45
52
|
# Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
|
46
|
-
def
|
53
|
+
def to_fs(format = :default)
|
47
54
|
if formatter = DATE_FORMATS[format]
|
48
55
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
49
56
|
else
|
57
|
+
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
|
50
58
|
to_default_s
|
51
59
|
end
|
52
60
|
end
|
61
|
+
alias_method :to_formatted_s, :to_fs
|
53
62
|
alias_method :to_default_s, :to_s
|
54
|
-
alias_method :to_s, :to_formatted_s
|
55
63
|
|
56
|
-
# Returns the
|
64
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
65
|
+
# string if the time zone is already UTC.
|
57
66
|
#
|
58
67
|
# Time.local(2000).formatted_offset # => "-06:00"
|
59
68
|
# Time.local(2000).formatted_offset(false) # => "-0600"
|
60
69
|
def formatted_offset(colon = true, alternate_utc_string = nil)
|
61
70
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
62
71
|
end
|
72
|
+
|
73
|
+
# Aliased to +xmlschema+ for compatibility with +DateTime+
|
74
|
+
alias_method :rfc3339, :xmlschema
|
63
75
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
class Time
|
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
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
|
11
|
+
)
|
12
|
+
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
13
|
+
elsif format == NOT_SET
|
14
|
+
to_default_s
|
15
|
+
else
|
16
|
+
ActiveSupport::Deprecation.warn(
|
17
|
+
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_fs(#{format.inspect}) instead."
|
18
|
+
)
|
19
|
+
to_default_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|