activesupport 4.0.13 → 5.2.5
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 +412 -444
- data/MIT-LICENSE +2 -2
- data/README.rdoc +8 -4
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +14 -12
- data/lib/active_support/benchmarkable.rb +6 -14
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +67 -51
- data/lib/active_support/cache/mem_cache_store.rb +95 -97
- data/lib/active_support/cache/memory_store.rb +28 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +466 -0
- data/lib/active_support/cache/strategy/local_cache.rb +70 -56
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +331 -206
- data/lib/active_support/callbacks.rb +697 -426
- data/lib/active_support/concern.rb +32 -10
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/core_ext/array/access.rb +39 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -35
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +23 -13
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -7
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- 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 +41 -23
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +20 -8
- 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 +21 -9
- data/lib/active_support/core_ext/date/conversions.rb +32 -22
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +41 -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 +78 -37
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
- data/lib/active_support/core_ext/date_time.rb +7 -4
- data/lib/active_support/core_ext/digest/uuid.rb +53 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +113 -29
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +29 -0
- 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/except.rb +12 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +50 -38
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +12 -6
- data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
- data/lib/active_support/core_ext/hash.rb +11 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- 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/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/marshal.rb +13 -10
- 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 +170 -21
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +134 -0
- data/lib/active_support/core_ext/module/delegation.rb +135 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -25
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -10
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -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 +12 -1
- data/lib/active_support/core_ext/object/blank.rb +70 -19
- 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 +100 -34
- 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 +227 -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 +94 -24
- data/lib/active_support/core_ext/object/with_options.rb +45 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -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 +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +41 -39
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +17 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +55 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +114 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -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/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +123 -110
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +23 -14
- data/lib/active_support/core_ext/time/zones.rb +42 -26
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +196 -166
- data/lib/active_support/deprecation/behaviors.rb +48 -15
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +14 -11
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +354 -34
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- 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 +158 -35
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +38 -20
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +79 -30
- data/lib/active_support/inflector/methods.rb +197 -129
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +21 -25
- data/lib/active_support/json/encoding.rb +84 -292
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +26 -28
- data/lib/active_support/lazy_load_hooks.rb +51 -21
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +54 -3
- data/lib/active_support/logger_silence.rb +12 -7
- data/lib/active_support/logger_thread_safe_level.rb +34 -0
- data/lib/active_support/message_encryptor.rb +173 -50
- data/lib/active_support/message_verifier.rb +159 -22
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +38 -26
- data/lib/active_support/multibyte/unicode.rb +138 -146
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +23 -16
- data/lib/active_support/notifications/instrumenter.rb +29 -8
- data/lib/active_support/notifications.rb +22 -13
- data/lib/active_support/number_helper/number_converter.rb +184 -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 +29 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +125 -391
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +31 -5
- data/lib/active_support/per_thread_registry.rb +19 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +31 -0
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +54 -17
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +42 -37
- data/lib/active_support/testing/assertions.rb +126 -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 +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +55 -86
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +5 -3
- data/lib/active_support/testing/time_helpers.rb +200 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +223 -73
- data/lib/active_support/values/time_zone.rb +261 -126
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +116 -113
- data/lib/active_support/xml_mini/libxml.rb +17 -16
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +15 -15
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +17 -16
- data/lib/active_support/xml_mini.rb +69 -51
- data/lib/active_support.rb +29 -3
- metadata +84 -54
- 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/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/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- 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/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
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class String
|
4
4
|
# Strips indentation in heredocs.
|
@@ -17,10 +17,9 @@ class String
|
|
17
17
|
#
|
18
18
|
# the user would see the usage message aligned against the left margin.
|
19
19
|
#
|
20
|
-
# Technically, it looks for the least indented line
|
21
|
-
# that amount of leading whitespace.
|
20
|
+
# Technically, it looks for the least indented non-empty line
|
21
|
+
# in the whole string, and removes that amount of leading whitespace.
|
22
22
|
def strip_heredoc
|
23
|
-
|
24
|
-
gsub(/^[ \t]{#{indent}}/, '')
|
23
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
|
25
24
|
end
|
26
25
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/time/zones"
|
2
5
|
|
3
6
|
class String
|
4
7
|
# Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/string/filters"
|
5
|
+
require "active_support/core_ext/string/multibyte"
|
6
|
+
require "active_support/core_ext/string/starts_ends_with"
|
7
|
+
require "active_support/core_ext/string/inflections"
|
8
|
+
require "active_support/core_ext/string/access"
|
9
|
+
require "active_support/core_ext/string/behavior"
|
10
|
+
require "active_support/core_ext/string/output_safety"
|
11
|
+
require "active_support/core_ext/string/exclude"
|
12
|
+
require "active_support/core_ext/string/strip"
|
13
|
+
require "active_support/core_ext/string/inquiry"
|
14
|
+
require "active_support/core_ext/string/indent"
|
15
|
+
require "active_support/core_ext/string/zones"
|
@@ -1,9 +1,11 @@
|
|
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"
|
7
9
|
|
8
10
|
class Time
|
9
11
|
include DateAndTime::Calculations
|
@@ -16,9 +18,9 @@ class Time
|
|
16
18
|
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
|
17
19
|
end
|
18
20
|
|
19
|
-
#
|
21
|
+
# Returns the number of days in the given month.
|
20
22
|
# If no year is specified, it will use the current year.
|
21
|
-
def days_in_month(month, year =
|
23
|
+
def days_in_month(month, year = current.year)
|
22
24
|
if month == 2 && ::Date.gregorian_leap?(year)
|
23
25
|
29
|
24
26
|
else
|
@@ -26,39 +28,10 @@ class Time
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
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)
|
31
|
+
# Returns the number of days in the given year.
|
32
|
+
# If no year is specified, it will use the current year.
|
33
|
+
def days_in_year(year = current.year)
|
34
|
+
days_in_month(2, year) + 337
|
62
35
|
end
|
63
36
|
|
64
37
|
# 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>.
|
@@ -82,11 +55,38 @@ class Time
|
|
82
55
|
end
|
83
56
|
alias_method :at_without_coercion, :at
|
84
57
|
alias_method :at, :at_with_coercion
|
58
|
+
|
59
|
+
# Creates a +Time+ instance from an RFC 3339 string.
|
60
|
+
#
|
61
|
+
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
62
|
+
#
|
63
|
+
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
64
|
+
#
|
65
|
+
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
66
|
+
def rfc3339(str)
|
67
|
+
parts = Date._rfc3339(str)
|
68
|
+
|
69
|
+
raise ArgumentError, "invalid date" if parts.empty?
|
70
|
+
|
71
|
+
Time.new(
|
72
|
+
parts.fetch(:year),
|
73
|
+
parts.fetch(:mon),
|
74
|
+
parts.fetch(:mday),
|
75
|
+
parts.fetch(:hour),
|
76
|
+
parts.fetch(:min),
|
77
|
+
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
78
|
+
parts.fetch(:offset)
|
79
|
+
)
|
80
|
+
end
|
85
81
|
end
|
86
82
|
|
87
|
-
#
|
83
|
+
# Returns the number of seconds since 00:00:00.
|
84
|
+
#
|
85
|
+
# Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
|
86
|
+
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
87
|
+
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
88
88
|
def seconds_since_midnight
|
89
|
-
to_i - change(:
|
89
|
+
to_i - change(hour: 0).to_i + (usec / 1.0e+6)
|
90
90
|
end
|
91
91
|
|
92
92
|
# Returns the number of seconds until 23:59:59.
|
@@ -98,39 +98,67 @@ class Time
|
|
98
98
|
end_of_day.to_i - to_i
|
99
99
|
end
|
100
100
|
|
101
|
+
# Returns the fraction of a second as a +Rational+
|
102
|
+
#
|
103
|
+
# Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
|
104
|
+
def sec_fraction
|
105
|
+
subsec
|
106
|
+
end
|
107
|
+
|
101
108
|
# Returns a new Time where one or more of the elements have been changed according
|
102
109
|
# 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
|
110
|
+
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
111
|
+
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
112
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
113
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
114
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
115
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
108
116
|
#
|
109
117
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
110
118
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
111
119
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
112
120
|
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
|
-
|
121
|
+
new_year = options.fetch(:year, year)
|
122
|
+
new_month = options.fetch(:month, month)
|
123
|
+
new_day = options.fetch(:day, day)
|
124
|
+
new_hour = options.fetch(:hour, hour)
|
125
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
126
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
127
|
+
new_offset = options.fetch(:offset, nil)
|
128
|
+
|
129
|
+
if new_nsec = options[:nsec]
|
130
|
+
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
131
|
+
new_usec = Rational(new_nsec, 1000)
|
132
|
+
else
|
133
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
134
|
+
end
|
135
|
+
|
136
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
137
|
+
|
138
|
+
new_sec += Rational(new_usec, 1000000)
|
139
|
+
|
140
|
+
if new_offset
|
141
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
142
|
+
elsif utc?
|
143
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
123
144
|
elsif zone
|
124
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
145
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
125
146
|
else
|
126
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec
|
147
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
127
148
|
end
|
128
149
|
end
|
129
150
|
|
130
|
-
# Uses Date to provide precise Time calculations for years, months, and days
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# <tt>:
|
151
|
+
# Uses Date to provide precise Time calculations for years, months, and days
|
152
|
+
# according to the proleptic Gregorian calendar. The +options+ parameter
|
153
|
+
# takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
|
154
|
+
# <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
|
155
|
+
# <tt>:seconds</tt>.
|
156
|
+
#
|
157
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
|
158
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
|
159
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
|
160
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
|
161
|
+
# Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
|
134
162
|
def advance(options)
|
135
163
|
unless options[:weeks].nil?
|
136
164
|
options[:weeks], partial_weeks = options[:weeks].divmod(1)
|
@@ -143,7 +171,8 @@ class Time
|
|
143
171
|
end
|
144
172
|
|
145
173
|
d = to_date.advance(options)
|
146
|
-
|
174
|
+
d = d.gregorian if d.julian?
|
175
|
+
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
147
176
|
seconds_to_advance = \
|
148
177
|
options.fetch(:seconds, 0) +
|
149
178
|
options.fetch(:minutes, 0) * 60 +
|
@@ -171,81 +200,64 @@ class Time
|
|
171
200
|
|
172
201
|
# Returns a new Time representing the start of the day (0:00)
|
173
202
|
def beginning_of_day
|
174
|
-
|
175
|
-
change(:hour => 0)
|
203
|
+
change(hour: 0)
|
176
204
|
end
|
177
205
|
alias :midnight :beginning_of_day
|
178
206
|
alias :at_midnight :beginning_of_day
|
179
207
|
alias :at_beginning_of_day :beginning_of_day
|
180
208
|
|
181
|
-
# Returns a new Time representing the
|
209
|
+
# Returns a new Time representing the middle of the day (12:00)
|
210
|
+
def middle_of_day
|
211
|
+
change(hour: 12)
|
212
|
+
end
|
213
|
+
alias :midday :middle_of_day
|
214
|
+
alias :noon :middle_of_day
|
215
|
+
alias :at_midday :middle_of_day
|
216
|
+
alias :at_noon :middle_of_day
|
217
|
+
alias :at_middle_of_day :middle_of_day
|
218
|
+
|
219
|
+
# Returns a new Time representing the end of the day, 23:59:59.999999
|
182
220
|
def end_of_day
|
183
221
|
change(
|
184
|
-
:
|
185
|
-
:
|
186
|
-
:
|
187
|
-
:
|
222
|
+
hour: 23,
|
223
|
+
min: 59,
|
224
|
+
sec: 59,
|
225
|
+
usec: Rational(999999999, 1000)
|
188
226
|
)
|
189
227
|
end
|
190
228
|
alias :at_end_of_day :end_of_day
|
191
229
|
|
192
230
|
# Returns a new Time representing the start of the hour (x:00)
|
193
231
|
def beginning_of_hour
|
194
|
-
change(:
|
232
|
+
change(min: 0)
|
195
233
|
end
|
196
234
|
alias :at_beginning_of_hour :beginning_of_hour
|
197
235
|
|
198
|
-
# Returns a new Time representing the end of the hour, x:59:59.999999
|
236
|
+
# Returns a new Time representing the end of the hour, x:59:59.999999
|
199
237
|
def end_of_hour
|
200
238
|
change(
|
201
|
-
:
|
202
|
-
:
|
203
|
-
:
|
239
|
+
min: 59,
|
240
|
+
sec: 59,
|
241
|
+
usec: Rational(999999999, 1000)
|
204
242
|
)
|
205
243
|
end
|
206
244
|
alias :at_end_of_hour :end_of_hour
|
207
245
|
|
208
246
|
# Returns a new Time representing the start of the minute (x:xx:00)
|
209
247
|
def beginning_of_minute
|
210
|
-
change(:
|
248
|
+
change(sec: 0)
|
211
249
|
end
|
212
250
|
alias :at_beginning_of_minute :beginning_of_minute
|
213
251
|
|
214
|
-
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
252
|
+
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
215
253
|
def end_of_minute
|
216
254
|
change(
|
217
|
-
:
|
218
|
-
:
|
255
|
+
sec: 59,
|
256
|
+
usec: Rational(999999999, 1000)
|
219
257
|
)
|
220
258
|
end
|
221
259
|
alias :at_end_of_minute :end_of_minute
|
222
260
|
|
223
|
-
# Returns a Range representing the whole day of the current time.
|
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
261
|
def plus_with_duration(other) #:nodoc:
|
250
262
|
if ActiveSupport::Duration === other
|
251
263
|
other.since(self)
|
@@ -279,8 +291,10 @@ class Time
|
|
279
291
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
280
292
|
# can be chronologically compared with a Time
|
281
293
|
def compare_with_coercion(other)
|
282
|
-
# we're avoiding Time#to_datetime
|
283
|
-
if other.
|
294
|
+
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
|
295
|
+
if other.class == Time
|
296
|
+
compare_without_coercion(other)
|
297
|
+
elsif other.is_a?(Time)
|
284
298
|
compare_without_coercion(other.to_time)
|
285
299
|
else
|
286
300
|
to_datetime <=> other
|
@@ -298,5 +312,4 @@ class Time
|
|
298
312
|
end
|
299
313
|
alias_method :eql_without_coercion, :eql?
|
300
314
|
alias_method :eql?, :eql_with_coercion
|
301
|
-
|
302
315
|
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,29 +1,33 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/inflector/methods"
|
4
|
+
require "active_support/values/time_zone"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
DATE_FORMATS = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
8
|
+
db: "%Y-%m-%d %H:%M:%S",
|
9
|
+
number: "%Y%m%d%H%M%S",
|
10
|
+
nsec: "%Y%m%d%H%M%S%9N",
|
11
|
+
usec: "%Y%m%d%H%M%S%6N",
|
12
|
+
time: "%H:%M",
|
13
|
+
short: "%d %b %H:%M",
|
14
|
+
long: "%B %d, %Y %H:%M",
|
15
|
+
long_ordinal: lambda { |time|
|
13
16
|
day_format = ActiveSupport::Inflector.ordinalize(time.day)
|
14
17
|
time.strftime("%B #{day_format}, %Y %H:%M")
|
15
18
|
},
|
16
|
-
:
|
19
|
+
rfc822: lambda { |time|
|
17
20
|
offset_format = time.formatted_offset(false)
|
18
21
|
time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
|
19
|
-
}
|
22
|
+
},
|
23
|
+
iso8601: lambda { |time| time.iso8601 }
|
20
24
|
}
|
21
25
|
|
22
|
-
# Converts to a formatted string. See DATE_FORMATS for
|
26
|
+
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
23
27
|
#
|
24
28
|
# This method is aliased to <tt>to_s</tt>.
|
25
29
|
#
|
26
|
-
# time = Time.now # =>
|
30
|
+
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
27
31
|
#
|
28
32
|
# time.to_formatted_s(:time) # => "06:10"
|
29
33
|
# time.to_s(:time) # => "06:10"
|
@@ -34,6 +38,7 @@ class Time
|
|
34
38
|
# time.to_formatted_s(:long) # => "January 18, 2007 06:10"
|
35
39
|
# time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
|
36
40
|
# time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
|
41
|
+
# time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00"
|
37
42
|
#
|
38
43
|
# == Adding your own time formats to +to_formatted_s+
|
39
44
|
# You can add your own formats to the Time::DATE_FORMATS hash.
|
@@ -53,11 +58,15 @@ class Time
|
|
53
58
|
alias_method :to_default_s, :to_s
|
54
59
|
alias_method :to_s, :to_formatted_s
|
55
60
|
|
56
|
-
# Returns the
|
61
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
62
|
+
# string if the time zone is already UTC.
|
57
63
|
#
|
58
64
|
# Time.local(2000).formatted_offset # => "-06:00"
|
59
65
|
# Time.local(2000).formatted_offset(false) # => "-0600"
|
60
66
|
def formatted_offset(colon = true, alternate_utc_string = nil)
|
61
67
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
62
68
|
end
|
69
|
+
|
70
|
+
# Aliased to +xmlschema+ for compatibility with +DateTime+
|
71
|
+
alias_method :rfc3339, :xmlschema
|
63
72
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/time_with_zone"
|
4
|
+
require "active_support/core_ext/time/acts_like"
|
5
|
+
require "active_support/core_ext/date_and_time/zones"
|
3
6
|
|
4
7
|
class Time
|
8
|
+
include DateAndTime::Zones
|
5
9
|
class << self
|
6
10
|
attr_accessor :zone_default
|
7
11
|
|
@@ -24,7 +28,7 @@ class Time
|
|
24
28
|
# <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
|
25
29
|
#
|
26
30
|
# class ApplicationController < ActionController::Base
|
27
|
-
#
|
31
|
+
# around_action :set_time_zone
|
28
32
|
#
|
29
33
|
# def set_time_zone
|
30
34
|
# if logged_in?
|
@@ -38,7 +42,23 @@ class Time
|
|
38
42
|
Thread.current[:time_zone] = find_zone!(time_zone)
|
39
43
|
end
|
40
44
|
|
41
|
-
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
45
|
+
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
46
|
+
# resets <tt>Time.zone</tt> to existing value when done.
|
47
|
+
#
|
48
|
+
# class ApplicationController < ActionController::Base
|
49
|
+
# around_action :set_time_zone
|
50
|
+
#
|
51
|
+
# private
|
52
|
+
#
|
53
|
+
# def set_time_zone
|
54
|
+
# Time.use_zone(current_user.timezone) { yield }
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
|
59
|
+
# objects that have already been created, e.g. any model timestamp
|
60
|
+
# attributes that have been read before the block will remain in
|
61
|
+
# the application's default timezone.
|
42
62
|
def use_zone(time_zone)
|
43
63
|
new_zone = find_zone!(time_zone)
|
44
64
|
begin
|
@@ -49,12 +69,22 @@ class Time
|
|
49
69
|
end
|
50
70
|
end
|
51
71
|
|
52
|
-
# Returns a TimeZone instance
|
72
|
+
# Returns a TimeZone instance matching the time zone provided.
|
73
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
74
|
+
# Raises an +ArgumentError+ for invalid time zones.
|
75
|
+
#
|
76
|
+
# Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
77
|
+
# Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
|
78
|
+
# Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
|
79
|
+
# Time.find_zone! nil # => nil
|
80
|
+
# Time.find_zone! false # => false
|
81
|
+
# Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
|
53
82
|
def find_zone!(time_zone)
|
54
83
|
if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
|
55
84
|
time_zone
|
56
85
|
else
|
57
|
-
#
|
86
|
+
# Look up the timezone based on the identifier (unless we've been
|
87
|
+
# passed a TZInfo::Timezone)
|
58
88
|
unless time_zone.respond_to?(:period_for_local)
|
59
89
|
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
60
90
|
end
|
@@ -70,28 +100,14 @@ class Time
|
|
70
100
|
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
71
101
|
end
|
72
102
|
|
103
|
+
# Returns a TimeZone instance matching the time zone provided.
|
104
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
105
|
+
# Returns +nil+ for invalid time zones.
|
106
|
+
#
|
107
|
+
# Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
108
|
+
# Time.find_zone "NOT-A-TIMEZONE" # => nil
|
73
109
|
def find_zone(time_zone)
|
74
110
|
find_zone!(time_zone) rescue nil
|
75
111
|
end
|
76
112
|
end
|
77
|
-
|
78
|
-
# Returns the simultaneous time in <tt>Time.zone</tt>.
|
79
|
-
#
|
80
|
-
# Time.zone = 'Hawaii' # => 'Hawaii'
|
81
|
-
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
82
|
-
#
|
83
|
-
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
|
84
|
-
# instead of the operating system's time zone.
|
85
|
-
#
|
86
|
-
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
|
87
|
-
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
88
|
-
#
|
89
|
-
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
90
|
-
def in_time_zone(zone = ::Time.zone)
|
91
|
-
if zone
|
92
|
-
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
|
93
|
-
else
|
94
|
-
self
|
95
|
-
end
|
96
|
-
end
|
97
113
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/time/acts_like"
|
4
|
+
require "active_support/core_ext/time/calculations"
|
5
|
+
require "active_support/core_ext/time/compatibility"
|
6
|
+
require "active_support/core_ext/time/conversions"
|
7
|
+
require "active_support/core_ext/time/zones"
|
@@ -1,18 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
unless str == parser.unescape(parser.escape(str))
|
3
|
+
require "uri"
|
4
|
+
if RUBY_VERSION < "2.6.0"
|
5
|
+
require "active_support/core_ext/module/redefine_method"
|
8
6
|
URI::Parser.class_eval do
|
9
|
-
|
7
|
+
silence_redefinition_of_method :unescape
|
10
8
|
def unescape(str, escaped = /%[a-fA-F\d]{2}/)
|
11
9
|
# TODO: Are we actually sure that ASCII == UTF-8?
|
12
10
|
# YK: My initial experiments say yes, but let's be sure please
|
13
11
|
enc = str.encoding
|
14
12
|
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
15
|
-
str.gsub(escaped) { [
|
13
|
+
str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|