activesupport 4.2.11.1 → 5.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 +4 -4
- data/CHANGELOG.md +399 -440
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +461 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +287 -196
- data/lib/active_support/callbacks.rb +640 -590
- data/lib/active_support/concern.rb +11 -5
- 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 +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- 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 +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- 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 +36 -18
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +101 -33
- 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 +14 -9
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
- data/lib/active_support/core_ext/hash.rb +11 -9
- 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 -18
- 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 +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- 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 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +99 -29
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- 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 -11
- 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 +78 -81
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- 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 +27 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +41 -14
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +69 -21
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- 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 +8 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +6 -5
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -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 +34 -38
- 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 -2
- 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 +85 -51
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +152 -161
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- 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 +12 -9
- 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 +307 -35
- 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 +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +123 -28
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +37 -13
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +163 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +11 -58
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- 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 +8 -7
- data/lib/active_support/logger_silence.rb +6 -4
- data/lib/active_support/logger_thread_safe_level.rb +7 -5
- data/lib/active_support/message_encryptor.rb +168 -53
- data/lib/active_support/message_verifier.rb +150 -17
- 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 +36 -23
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +11 -9
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +94 -68
- 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 +23 -5
- data/lib/active_support/per_thread_registry.rb +9 -4
- 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 +15 -11
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +21 -16
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +19 -47
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- 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 +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +81 -15
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +169 -39
- data/lib/active_support/values/time_zone.rb +196 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -114
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +37 -37
- data/lib/active_support.rb +12 -11
- metadata +54 -24
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,23 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/try"
|
4
|
+
|
1
5
|
module DateAndTime
|
2
6
|
module Calculations
|
3
7
|
DAYS_INTO_WEEK = {
|
4
|
-
:
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
8
|
+
monday: 0,
|
9
|
+
tuesday: 1,
|
10
|
+
wednesday: 2,
|
11
|
+
thursday: 3,
|
12
|
+
friday: 4,
|
13
|
+
saturday: 5,
|
14
|
+
sunday: 6
|
11
15
|
}
|
16
|
+
WEEKEND_DAYS = [ 6, 0 ]
|
12
17
|
|
13
18
|
# Returns a new date/time representing yesterday.
|
14
19
|
def yesterday
|
15
|
-
advance(:
|
20
|
+
advance(days: -1)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a new date/time the specified number of days ago.
|
24
|
+
def prev_day(days = 1)
|
25
|
+
advance(days: -days)
|
16
26
|
end
|
17
27
|
|
18
28
|
# Returns a new date/time representing tomorrow.
|
19
29
|
def tomorrow
|
20
|
-
advance(:
|
30
|
+
advance(days: 1)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a new date/time the specified number of days in the future.
|
34
|
+
def next_day(days = 1)
|
35
|
+
advance(days: days)
|
21
36
|
end
|
22
37
|
|
23
38
|
# Returns true if the date/time is today.
|
@@ -35,76 +50,111 @@ module DateAndTime
|
|
35
50
|
self > self.class.current
|
36
51
|
end
|
37
52
|
|
53
|
+
# Returns true if the date/time falls on a Saturday or Sunday.
|
54
|
+
def on_weekend?
|
55
|
+
WEEKEND_DAYS.include?(wday)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns true if the date/time does not fall on a Saturday or Sunday.
|
59
|
+
def on_weekday?
|
60
|
+
!WEEKEND_DAYS.include?(wday)
|
61
|
+
end
|
62
|
+
|
38
63
|
# Returns a new date/time the specified number of days ago.
|
39
64
|
def days_ago(days)
|
40
|
-
advance(:
|
65
|
+
advance(days: -days)
|
41
66
|
end
|
42
67
|
|
43
68
|
# Returns a new date/time the specified number of days in the future.
|
44
69
|
def days_since(days)
|
45
|
-
advance(:
|
70
|
+
advance(days: days)
|
46
71
|
end
|
47
72
|
|
48
73
|
# Returns a new date/time the specified number of weeks ago.
|
49
74
|
def weeks_ago(weeks)
|
50
|
-
advance(:
|
75
|
+
advance(weeks: -weeks)
|
51
76
|
end
|
52
77
|
|
53
78
|
# Returns a new date/time the specified number of weeks in the future.
|
54
79
|
def weeks_since(weeks)
|
55
|
-
advance(:
|
80
|
+
advance(weeks: weeks)
|
56
81
|
end
|
57
82
|
|
58
83
|
# Returns a new date/time the specified number of months ago.
|
59
84
|
def months_ago(months)
|
60
|
-
advance(:
|
85
|
+
advance(months: -months)
|
61
86
|
end
|
62
87
|
|
63
88
|
# Returns a new date/time the specified number of months in the future.
|
64
89
|
def months_since(months)
|
65
|
-
advance(:
|
90
|
+
advance(months: months)
|
66
91
|
end
|
67
92
|
|
68
93
|
# Returns a new date/time the specified number of years ago.
|
69
94
|
def years_ago(years)
|
70
|
-
advance(:
|
95
|
+
advance(years: -years)
|
71
96
|
end
|
72
97
|
|
73
98
|
# Returns a new date/time the specified number of years in the future.
|
74
99
|
def years_since(years)
|
75
|
-
advance(:
|
100
|
+
advance(years: years)
|
76
101
|
end
|
77
102
|
|
78
103
|
# Returns a new date/time at the start of the month.
|
79
|
-
#
|
104
|
+
#
|
105
|
+
# today = Date.today # => Thu, 18 Jun 2015
|
106
|
+
# today.beginning_of_month # => Mon, 01 Jun 2015
|
107
|
+
#
|
108
|
+
# +DateTime+ objects will have a time set to 0:00.
|
109
|
+
#
|
110
|
+
# now = DateTime.current # => Thu, 18 Jun 2015 15:23:13 +0000
|
111
|
+
# now.beginning_of_month # => Mon, 01 Jun 2015 00:00:00 +0000
|
80
112
|
def beginning_of_month
|
81
|
-
first_hour(change(:
|
113
|
+
first_hour(change(day: 1))
|
82
114
|
end
|
83
115
|
alias :at_beginning_of_month :beginning_of_month
|
84
116
|
|
85
117
|
# Returns a new date/time at the start of the quarter.
|
86
|
-
#
|
87
|
-
#
|
118
|
+
#
|
119
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
120
|
+
# today.beginning_of_quarter # => Wed, 01 Jul 2015
|
121
|
+
#
|
122
|
+
# +DateTime+ objects will have a time set to 0:00.
|
123
|
+
#
|
124
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
125
|
+
# now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
|
88
126
|
def beginning_of_quarter
|
89
127
|
first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
|
90
|
-
beginning_of_month.change(:
|
128
|
+
beginning_of_month.change(month: first_quarter_month)
|
91
129
|
end
|
92
130
|
alias :at_beginning_of_quarter :beginning_of_quarter
|
93
131
|
|
94
132
|
# Returns a new date/time at the end of the quarter.
|
95
|
-
#
|
96
|
-
#
|
133
|
+
#
|
134
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
135
|
+
# today.end_of_quarter # => Wed, 30 Sep 2015
|
136
|
+
#
|
137
|
+
# +DateTime+ objects will have a time set to 23:59:59.
|
138
|
+
#
|
139
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
140
|
+
# now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
|
97
141
|
def end_of_quarter
|
98
142
|
last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
|
99
|
-
beginning_of_month.change(:
|
143
|
+
beginning_of_month.change(month: last_quarter_month).end_of_month
|
100
144
|
end
|
101
145
|
alias :at_end_of_quarter :end_of_quarter
|
102
146
|
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
147
|
+
# Returns a new date/time at the beginning of the year.
|
148
|
+
#
|
149
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
150
|
+
# today.beginning_of_year # => Thu, 01 Jan 2015
|
151
|
+
#
|
152
|
+
# +DateTime+ objects will have a time set to 0:00.
|
153
|
+
#
|
154
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
155
|
+
# now.beginning_of_year # => Thu, 01 Jan 2015 00:00:00 +0000
|
106
156
|
def beginning_of_year
|
107
|
-
change(:
|
157
|
+
change(month: 1).beginning_of_month
|
108
158
|
end
|
109
159
|
alias :at_beginning_of_year :beginning_of_year
|
110
160
|
|
@@ -115,21 +165,32 @@ module DateAndTime
|
|
115
165
|
#
|
116
166
|
# The +given_day_in_next_week+ defaults to the beginning of the week
|
117
167
|
# which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
|
168
|
+
# when set.
|
118
169
|
#
|
119
170
|
# today = Date.today # => Thu, 07 May 2015
|
120
171
|
# today.next_week(:friday) # => Fri, 15 May 2015
|
121
172
|
#
|
122
|
-
#
|
173
|
+
# +DateTime+ objects have their time set to 0:00 unless +same_time+ is true.
|
123
174
|
#
|
124
|
-
# now =
|
125
|
-
# now.next_week # => Mon, 11 May 2015 00:00:00
|
126
|
-
def next_week(given_day_in_next_week = Date.beginning_of_week)
|
127
|
-
first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
|
175
|
+
# now = DateTime.current # => Thu, 07 May 2015 13:31:16 +0000
|
176
|
+
# now.next_week # => Mon, 11 May 2015 00:00:00 +0000
|
177
|
+
def next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false)
|
178
|
+
result = first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
|
179
|
+
same_time ? copy_time_to(result) : result
|
128
180
|
end
|
129
181
|
|
130
|
-
#
|
131
|
-
def
|
132
|
-
|
182
|
+
# Returns a new date/time representing the next weekday.
|
183
|
+
def next_weekday
|
184
|
+
if next_day.on_weekend?
|
185
|
+
next_week(:monday, same_time: true)
|
186
|
+
else
|
187
|
+
next_day
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns a new date/time the specified number of months in the future.
|
192
|
+
def next_month(months = 1)
|
193
|
+
advance(months: months)
|
133
194
|
end
|
134
195
|
|
135
196
|
# Short-hand for months_since(3)
|
@@ -137,25 +198,40 @@ module DateAndTime
|
|
137
198
|
months_since(3)
|
138
199
|
end
|
139
200
|
|
140
|
-
#
|
141
|
-
def next_year
|
142
|
-
|
201
|
+
# Returns a new date/time the specified number of years in the future.
|
202
|
+
def next_year(years = 1)
|
203
|
+
advance(years: years)
|
143
204
|
end
|
144
205
|
|
145
206
|
# Returns a new date/time representing the given day in the previous week.
|
146
207
|
# Week is assumed to start on +start_day+, default is
|
147
208
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
148
|
-
# DateTime objects have their time set to 0:00.
|
149
|
-
def prev_week(start_day = Date.beginning_of_week)
|
150
|
-
first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
|
209
|
+
# DateTime objects have their time set to 0:00 unless +same_time+ is true.
|
210
|
+
def prev_week(start_day = Date.beginning_of_week, same_time: false)
|
211
|
+
result = first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
|
212
|
+
same_time ? copy_time_to(result) : result
|
151
213
|
end
|
152
214
|
alias_method :last_week, :prev_week
|
153
215
|
|
216
|
+
# Returns a new date/time representing the previous weekday.
|
217
|
+
def prev_weekday
|
218
|
+
if prev_day.on_weekend?
|
219
|
+
copy_time_to(beginning_of_week(:friday))
|
220
|
+
else
|
221
|
+
prev_day
|
222
|
+
end
|
223
|
+
end
|
224
|
+
alias_method :last_weekday, :prev_weekday
|
225
|
+
|
226
|
+
# Returns a new date/time the specified number of months ago.
|
227
|
+
def prev_month(months = 1)
|
228
|
+
advance(months: -months)
|
229
|
+
end
|
230
|
+
|
154
231
|
# Short-hand for months_ago(1).
|
155
|
-
def
|
232
|
+
def last_month
|
156
233
|
months_ago(1)
|
157
234
|
end
|
158
|
-
alias_method :last_month, :prev_month
|
159
235
|
|
160
236
|
# Short-hand for months_ago(3).
|
161
237
|
def prev_quarter
|
@@ -163,11 +239,15 @@ module DateAndTime
|
|
163
239
|
end
|
164
240
|
alias_method :last_quarter, :prev_quarter
|
165
241
|
|
242
|
+
# Returns a new date/time the specified number of years ago.
|
243
|
+
def prev_year(years = 1)
|
244
|
+
advance(years: -years)
|
245
|
+
end
|
246
|
+
|
166
247
|
# Short-hand for years_ago(1).
|
167
|
-
def
|
248
|
+
def last_year
|
168
249
|
years_ago(1)
|
169
250
|
end
|
170
|
-
alias_method :last_year, :prev_year
|
171
251
|
|
172
252
|
# Returns the number of days to the start of the week on the given day.
|
173
253
|
# Week is assumed to start on +start_day+, default is
|
@@ -220,12 +300,17 @@ module DateAndTime
|
|
220
300
|
# Returns a new date/time representing the end of the year.
|
221
301
|
# DateTime objects will have a time set to 23:59:59.
|
222
302
|
def end_of_year
|
223
|
-
change(:
|
303
|
+
change(month: 12).end_of_month
|
224
304
|
end
|
225
305
|
alias :at_end_of_year :end_of_year
|
226
306
|
|
307
|
+
# Returns a Range representing the whole day of the current date/time.
|
308
|
+
def all_day
|
309
|
+
beginning_of_day..end_of_day
|
310
|
+
end
|
311
|
+
|
227
312
|
# Returns a Range representing the whole week of the current date/time.
|
228
|
-
# Week starts on start_day, default is <tt>Date.
|
313
|
+
# Week starts on start_day, default is <tt>Date.beginning_of_week</tt> or <tt>config.beginning_of_week</tt> when set.
|
229
314
|
def all_week(start_day = Date.beginning_of_week)
|
230
315
|
beginning_of_week(start_day)..end_of_week(start_day)
|
231
316
|
end
|
@@ -245,18 +330,45 @@ module DateAndTime
|
|
245
330
|
beginning_of_year..end_of_year
|
246
331
|
end
|
247
332
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
333
|
+
# Returns a new date/time representing the next occurrence of the specified day of week.
|
334
|
+
#
|
335
|
+
# today = Date.today # => Thu, 14 Dec 2017
|
336
|
+
# today.next_occurring(:monday) # => Mon, 18 Dec 2017
|
337
|
+
# today.next_occurring(:thursday) # => Thu, 21 Dec 2017
|
338
|
+
def next_occurring(day_of_week)
|
339
|
+
current_day_number = wday != 0 ? wday - 1 : 6
|
340
|
+
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
|
341
|
+
from_now += 7 unless from_now > 0
|
342
|
+
advance(days: from_now)
|
252
343
|
end
|
253
344
|
|
254
|
-
|
255
|
-
|
345
|
+
# Returns a new date/time representing the previous occurrence of the specified day of week.
|
346
|
+
#
|
347
|
+
# today = Date.today # => Thu, 14 Dec 2017
|
348
|
+
# today.prev_occurring(:monday) # => Mon, 11 Dec 2017
|
349
|
+
# today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
|
350
|
+
def prev_occurring(day_of_week)
|
351
|
+
current_day_number = wday != 0 ? wday - 1 : 6
|
352
|
+
ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
|
353
|
+
ago += 7 unless ago > 0
|
354
|
+
advance(days: -ago)
|
256
355
|
end
|
257
356
|
|
258
|
-
|
259
|
-
(
|
260
|
-
|
357
|
+
private
|
358
|
+
def first_hour(date_or_time)
|
359
|
+
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
|
360
|
+
end
|
361
|
+
|
362
|
+
def last_hour(date_or_time)
|
363
|
+
date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
|
364
|
+
end
|
365
|
+
|
366
|
+
def days_span(day)
|
367
|
+
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
|
368
|
+
end
|
369
|
+
|
370
|
+
def copy_time_to(other)
|
371
|
+
other.change(hour: hour, min: min, sec: sec, nsec: try(:nsec))
|
372
|
+
end
|
261
373
|
end
|
262
374
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
4
|
|
4
5
|
module DateAndTime
|
5
6
|
module Compatibility
|
@@ -10,6 +11,6 @@ module DateAndTime
|
|
10
11
|
# of the receiver. For backwards compatibility we're overriding
|
11
12
|
# this behavior, but new apps will have an initializer that sets
|
12
13
|
# this to true, because the new behavior is preferred.
|
13
|
-
mattr_accessor
|
14
|
+
mattr_accessor :preserve_timezone, instance_writer: false, default: false
|
14
15
|
end
|
15
16
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DateAndTime
|
2
4
|
module Zones
|
3
5
|
# Returns the simultaneous time in <tt>Time.zone</tt> if a zone is given or
|
4
6
|
# if Time.zone_default is set. Otherwise, it returns the current time.
|
5
7
|
#
|
6
8
|
# Time.zone = 'Hawaii' # => 'Hawaii'
|
7
|
-
#
|
8
|
-
# Date.new(2000).in_time_zone
|
9
|
+
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
10
|
+
# Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
|
9
11
|
#
|
10
12
|
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
|
11
13
|
# instead of the operating system's time zone.
|
@@ -14,8 +16,7 @@ module DateAndTime
|
|
14
16
|
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
15
17
|
#
|
16
18
|
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
17
|
-
#
|
18
|
-
# Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
|
19
|
+
# Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
|
19
20
|
def in_time_zone(zone = ::Time.zone)
|
20
21
|
time_zone = ::Time.find_zone! zone
|
21
22
|
time = acts_like?(:time) ? self : nil
|
@@ -23,19 +24,18 @@ module DateAndTime
|
|
23
24
|
if time_zone
|
24
25
|
time_with_zone(time, time_zone)
|
25
26
|
else
|
26
|
-
time ||
|
27
|
+
time || to_time
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
def time_with_zone(time, zone)
|
34
|
+
if time
|
35
|
+
ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone)
|
36
|
+
else
|
37
|
+
ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc))
|
38
|
+
end
|
37
39
|
end
|
38
|
-
end
|
39
40
|
end
|
40
41
|
end
|
41
|
-
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
2
4
|
|
3
5
|
class DateTime
|
4
6
|
class << self
|
@@ -10,7 +12,11 @@ class DateTime
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
|
-
#
|
15
|
+
# Returns the number of seconds since 00:00:00.
|
16
|
+
#
|
17
|
+
# DateTime.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0
|
18
|
+
# DateTime.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296
|
19
|
+
# DateTime.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399
|
14
20
|
def seconds_since_midnight
|
15
21
|
sec + (min * 60) + (hour * 3600)
|
16
22
|
end
|
@@ -43,13 +49,23 @@ class DateTime
|
|
43
49
|
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
|
44
50
|
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
|
45
51
|
def change(options)
|
52
|
+
if new_nsec = options[:nsec]
|
53
|
+
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
54
|
+
new_fraction = Rational(new_nsec, 1000000000)
|
55
|
+
else
|
56
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
57
|
+
new_fraction = Rational(new_usec, 1000000)
|
58
|
+
end
|
59
|
+
|
60
|
+
raise ArgumentError, "argument out of range" if new_fraction >= 1
|
61
|
+
|
46
62
|
::DateTime.civil(
|
47
63
|
options.fetch(:year, year),
|
48
64
|
options.fetch(:month, month),
|
49
65
|
options.fetch(:day, day),
|
50
66
|
options.fetch(:hour, hour),
|
51
67
|
options.fetch(:min, options[:hour] ? 0 : min),
|
52
|
-
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec +
|
68
|
+
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction,
|
53
69
|
options.fetch(:offset, offset),
|
54
70
|
options.fetch(:start, start)
|
55
71
|
)
|
@@ -71,7 +87,7 @@ class DateTime
|
|
71
87
|
end
|
72
88
|
|
73
89
|
d = to_date.advance(options)
|
74
|
-
datetime_advanced_by_date = change(:
|
90
|
+
datetime_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
75
91
|
seconds_to_advance = \
|
76
92
|
options.fetch(:seconds, 0) +
|
77
93
|
options.fetch(:minutes, 0) * 60 +
|
@@ -100,7 +116,7 @@ class DateTime
|
|
100
116
|
|
101
117
|
# Returns a new DateTime representing the start of the day (0:00).
|
102
118
|
def beginning_of_day
|
103
|
-
change(:
|
119
|
+
change(hour: 0)
|
104
120
|
end
|
105
121
|
alias :midnight :beginning_of_day
|
106
122
|
alias :at_midnight :beginning_of_day
|
@@ -108,7 +124,7 @@ class DateTime
|
|
108
124
|
|
109
125
|
# Returns a new DateTime representing the middle of the day (12:00)
|
110
126
|
def middle_of_day
|
111
|
-
change(:
|
127
|
+
change(hour: 12)
|
112
128
|
end
|
113
129
|
alias :midday :middle_of_day
|
114
130
|
alias :noon :middle_of_day
|
@@ -118,31 +134,31 @@ class DateTime
|
|
118
134
|
|
119
135
|
# Returns a new DateTime representing the end of the day (23:59:59).
|
120
136
|
def end_of_day
|
121
|
-
change(:
|
137
|
+
change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
|
122
138
|
end
|
123
139
|
alias :at_end_of_day :end_of_day
|
124
140
|
|
125
141
|
# Returns a new DateTime representing the start of the hour (hh:00:00).
|
126
142
|
def beginning_of_hour
|
127
|
-
change(:
|
143
|
+
change(min: 0)
|
128
144
|
end
|
129
145
|
alias :at_beginning_of_hour :beginning_of_hour
|
130
146
|
|
131
147
|
# Returns a new DateTime representing the end of the hour (hh:59:59).
|
132
148
|
def end_of_hour
|
133
|
-
change(:
|
149
|
+
change(min: 59, sec: 59, usec: Rational(999999999, 1000))
|
134
150
|
end
|
135
151
|
alias :at_end_of_hour :end_of_hour
|
136
152
|
|
137
153
|
# Returns a new DateTime representing the start of the minute (hh:mm:00).
|
138
154
|
def beginning_of_minute
|
139
|
-
change(:
|
155
|
+
change(sec: 0)
|
140
156
|
end
|
141
157
|
alias :at_beginning_of_minute :beginning_of_minute
|
142
158
|
|
143
159
|
# Returns a new DateTime representing the end of the minute (hh:mm:59).
|
144
160
|
def end_of_minute
|
145
|
-
change(:
|
161
|
+
change(sec: 59, usec: Rational(999999999, 1000))
|
146
162
|
end
|
147
163
|
alias :at_end_of_minute :end_of_minute
|
148
164
|
|
@@ -157,12 +173,17 @@ class DateTime
|
|
157
173
|
end
|
158
174
|
alias_method :getlocal, :localtime
|
159
175
|
|
160
|
-
# Returns a <tt>
|
176
|
+
# Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
|
161
177
|
#
|
162
178
|
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
|
163
179
|
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
|
164
180
|
def utc
|
165
|
-
new_offset(0)
|
181
|
+
utc = new_offset(0)
|
182
|
+
|
183
|
+
Time.utc(
|
184
|
+
utc.year, utc.month, utc.day,
|
185
|
+
utc.hour, utc.min, utc.sec + utc.sec_fraction
|
186
|
+
)
|
166
187
|
end
|
167
188
|
alias_method :getgm, :utc
|
168
189
|
alias_method :getutc, :utc
|
@@ -181,13 +202,10 @@ class DateTime
|
|
181
202
|
# Layers additional behavior on DateTime#<=> so that Time and
|
182
203
|
# ActiveSupport::TimeWithZone instances can be compared with a DateTime.
|
183
204
|
def <=>(other)
|
184
|
-
if other.
|
185
|
-
super
|
186
|
-
elsif other.respond_to? :to_datetime
|
205
|
+
if other.respond_to? :to_datetime
|
187
206
|
super other.to_datetime rescue nil
|
188
207
|
else
|
189
|
-
|
208
|
+
super
|
190
209
|
end
|
191
210
|
end
|
192
|
-
|
193
211
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
-
|
2
|
-
|
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"
|
3
5
|
|
4
6
|
class DateTime
|
5
7
|
include DateAndTime::Compatibility
|
6
8
|
|
7
|
-
|
9
|
+
silence_redefinition_of_method :to_time
|
8
10
|
|
9
|
-
# Either return an instance of
|
10
|
-
# as +self+ or an instance of
|
11
|
-
# in the
|
11
|
+
# Either return an instance of +Time+ with the same UTC offset
|
12
|
+
# as +self+ or an instance of +Time+ representing the same time
|
13
|
+
# in the local system timezone depending on the setting of
|
12
14
|
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
13
15
|
def to_time
|
14
16
|
preserve_timezone ? getlocal(utc_offset) : getlocal
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "active_support/inflector/methods"
|
5
|
+
require "active_support/core_ext/time/conversions"
|
6
|
+
require "active_support/core_ext/date_time/calculations"
|
7
|
+
require "active_support/values/time_zone"
|
6
8
|
|
7
9
|
class DateTime
|
8
10
|
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
@@ -40,6 +42,8 @@ class DateTime
|
|
40
42
|
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
41
43
|
alias_method :to_s, :to_formatted_s
|
42
44
|
|
45
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
46
|
+
# string if the time zone is already UTC.
|
43
47
|
#
|
44
48
|
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
45
49
|
# datetime.formatted_offset # => "-06:00"
|
@@ -62,7 +66,7 @@ class DateTime
|
|
62
66
|
# # => Sun, 01 Jan 2012 00:00:00 +0300
|
63
67
|
# DateTime.civil_from_format :local, 2012, 12, 17
|
64
68
|
# # => Mon, 17 Dec 2012 00:00:00 +0000
|
65
|
-
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
|
69
|
+
def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0)
|
66
70
|
if utc_or_local.to_sym == :local
|
67
71
|
offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
|
68
72
|
else
|
@@ -93,11 +97,11 @@ class DateTime
|
|
93
97
|
|
94
98
|
private
|
95
99
|
|
96
|
-
|
97
|
-
|
98
|
-
|
100
|
+
def offset_in_seconds
|
101
|
+
(offset * 86400).to_i
|
102
|
+
end
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
104
|
+
def seconds_since_unix_epoch
|
105
|
+
(jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
|
106
|
+
end
|
103
107
|
end
|