activesupport 4.0.13 → 4.2.11.3
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 +406 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -2
- data/lib/active_support/backtrace_cleaner.rb +8 -8
- data/lib/active_support/benchmarkable.rb +0 -10
- data/lib/active_support/cache/file_store.rb +32 -22
- data/lib/active_support/cache/mem_cache_store.rb +5 -7
- data/lib/active_support/cache/memory_store.rb +1 -0
- data/lib/active_support/cache/strategy/local_cache.rb +11 -30
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +75 -41
- data/lib/active_support/callbacks.rb +482 -261
- data/lib/active_support/concern.rb +23 -7
- data/lib/active_support/configurable.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +11 -1
- data/lib/active_support/core_ext/array/conversions.rb +2 -17
- data/lib/active_support/core_ext/array/grouping.rb +29 -12
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -2
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -15
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +16 -0
- data/lib/active_support/core_ext/class/attribute.rb +1 -2
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -170
- data/lib/active_support/core_ext/class/delegating_attributes.rb +13 -8
- data/lib/active_support/core_ext/class/subclasses.rb +0 -2
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/calculations.rb +10 -0
- data/lib/active_support/core_ext/date/conversions.rb +9 -1
- data/lib/active_support/core_ext/date/zones.rb +2 -33
- data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -11
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +45 -22
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
- data/lib/active_support/core_ext/date_time/zones.rb +3 -21
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +17 -1
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash/compact.rb +24 -0
- data/lib/active_support/core_ext/hash/conversions.rb +9 -8
- data/lib/active_support/core_ext/hash/except.rb +8 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -0
- data/lib/active_support/core_ext/hash/keys.rb +25 -19
- data/lib/active_support/core_ext/hash/slice.rb +8 -2
- data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
- data/lib/active_support/core_ext/hash.rb +2 -1
- data/lib/active_support/core_ext/integer/time.rb +0 -15
- data/lib/active_support/core_ext/kernel/concern.rb +10 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +13 -2
- data/lib/active_support/core_ext/kernel.rb +3 -2
- data/lib/active_support/core_ext/load_error.rb +4 -1
- data/lib/active_support/core_ext/marshal.rb +8 -5
- data/lib/active_support/core_ext/module/aliasing.rb +2 -2
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +160 -14
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +53 -25
- data/lib/active_support/core_ext/module/deprecation.rb +0 -2
- data/lib/active_support/core_ext/module/introspection.rb +0 -16
- data/lib/active_support/core_ext/module/method_transplanting.rb +13 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
- data/lib/active_support/core_ext/numeric/time.rb +4 -29
- data/lib/active_support/core_ext/object/blank.rb +44 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +6 -6
- data/lib/active_support/core_ext/object/duplicable.rb +72 -33
- data/lib/active_support/core_ext/object/inclusion.rb +16 -15
- data/lib/active_support/core_ext/object/itself.rb +15 -0
- data/lib/active_support/core_ext/object/json.rb +197 -0
- data/lib/active_support/core_ext/object/to_query.rb +14 -6
- data/lib/active_support/core_ext/object/try.rb +36 -14
- data/lib/active_support/core_ext/object/with_options.rb +30 -3
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/string/access.rb +35 -35
- data/lib/active_support/core_ext/string/conversions.rb +10 -9
- data/lib/active_support/core_ext/string/exclude.rb +3 -3
- data/lib/active_support/core_ext/string/filters.rb +51 -3
- data/lib/active_support/core_ext/string/inflections.rb +15 -10
- data/lib/active_support/core_ext/string/output_safety.rb +97 -33
- data/lib/active_support/core_ext/string/zones.rb +1 -0
- data/lib/active_support/core_ext/thread.rb +12 -5
- data/lib/active_support/core_ext/time/calculations.rb +47 -68
- data/lib/active_support/core_ext/time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/zones.rb +2 -20
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/dependencies/autoload.rb +1 -1
- data/lib/active_support/dependencies.rb +64 -25
- data/lib/active_support/deprecation/behaviors.rb +4 -4
- data/lib/active_support/deprecation.rb +4 -4
- data/lib/active_support/duration.rb +55 -11
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/hash_with_indifferent_access.rb +39 -11
- data/lib/active_support/i18n.rb +4 -4
- data/lib/active_support/i18n_railtie.rb +1 -7
- data/lib/active_support/inflections.rb +6 -1
- data/lib/active_support/inflector/inflections.rb +19 -19
- data/lib/active_support/inflector/methods.rb +66 -25
- data/lib/active_support/json/decoding.rb +15 -22
- data/lib/active_support/json/encoding.rb +125 -286
- data/lib/active_support/key_generator.rb +8 -10
- data/lib/active_support/lazy_load_hooks.rb +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +1 -1
- data/lib/active_support/logger.rb +51 -1
- data/lib/active_support/logger_silence.rb +7 -4
- data/lib/active_support/logger_thread_safe_level.rb +32 -0
- data/lib/active_support/message_encryptor.rb +14 -6
- data/lib/active_support/message_verifier.rb +16 -12
- data/lib/active_support/multibyte/chars.rb +2 -3
- data/lib/active_support/multibyte/unicode.rb +46 -58
- data/lib/active_support/notifications/fanout.rb +12 -7
- data/lib/active_support/notifications/instrumenter.rb +2 -1
- data/lib/active_support/notifications.rb +11 -6
- data/lib/active_support/number_helper/number_converter.rb +182 -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 +23 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +66 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +49 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +87 -0
- data/lib/active_support/number_helper.rb +32 -324
- data/lib/active_support/ordered_options.rb +8 -0
- data/lib/active_support/per_thread_registry.rb +13 -10
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/subscriber.rb +35 -3
- data/lib/active_support/test_case.rb +52 -19
- data/lib/active_support/testing/assertions.rb +1 -31
- data/lib/active_support/testing/autorun.rb +2 -2
- data/lib/active_support/testing/constant_lookup.rb +1 -5
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/isolation.rb +29 -69
- data/lib/active_support/testing/setup_and_teardown.rb +17 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -2
- data/lib/active_support/testing/time_helpers.rb +134 -0
- data/lib/active_support/time.rb +0 -2
- data/lib/active_support/time_with_zone.rb +60 -40
- data/lib/active_support/values/time_zone.rb +101 -101
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -7
- data/lib/active_support/xml_mini/jdom.rb +6 -5
- data/lib/active_support/xml_mini/libxml.rb +1 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
- data/lib/active_support/xml_mini/nokogiri.rb +1 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
- data/lib/active_support/xml_mini/rexml.rb +7 -8
- data/lib/active_support/xml_mini.rb +33 -15
- data/lib/active_support.rb +27 -2
- metadata +43 -43
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/logger.rb +0 -67
- 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/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
@@ -78,7 +78,7 @@ module DateAndTime
|
|
78
78
|
# Returns a new date/time at the start of the month.
|
79
79
|
# DateTime objects will have a time set to 0:00.
|
80
80
|
def beginning_of_month
|
81
|
-
first_hour
|
81
|
+
first_hour(change(:day => 1))
|
82
82
|
end
|
83
83
|
alias :at_beginning_of_month :beginning_of_month
|
84
84
|
|
@@ -109,11 +109,22 @@ module DateAndTime
|
|
109
109
|
alias :at_beginning_of_year :beginning_of_year
|
110
110
|
|
111
111
|
# Returns a new date/time representing the given day in the next week.
|
112
|
+
#
|
113
|
+
# today = Date.today # => Thu, 07 May 2015
|
114
|
+
# today.next_week # => Mon, 11 May 2015
|
115
|
+
#
|
112
116
|
# The +given_day_in_next_week+ defaults to the beginning of the week
|
113
117
|
# which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
|
118
|
+
#
|
119
|
+
# today = Date.today # => Thu, 07 May 2015
|
120
|
+
# today.next_week(:friday) # => Fri, 15 May 2015
|
121
|
+
#
|
114
122
|
# when set. +DateTime+ objects have their time set to 0:00.
|
123
|
+
#
|
124
|
+
# now = Time.current # => Thu, 07 May 2015 13:31:16 UTC +00:00
|
125
|
+
# now.next_week # => Mon, 11 May 2015 00:00:00 UTC +00:00
|
115
126
|
def next_week(given_day_in_next_week = Date.beginning_of_week)
|
116
|
-
first_hour
|
127
|
+
first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
|
117
128
|
end
|
118
129
|
|
119
130
|
# Short-hand for months_since(1).
|
@@ -136,7 +147,7 @@ module DateAndTime
|
|
136
147
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
137
148
|
# DateTime objects have their time set to 0:00.
|
138
149
|
def prev_week(start_day = Date.beginning_of_week)
|
139
|
-
first_hour
|
150
|
+
first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
|
140
151
|
end
|
141
152
|
alias_method :last_week, :prev_week
|
142
153
|
|
@@ -188,7 +199,7 @@ module DateAndTime
|
|
188
199
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
189
200
|
# DateTime objects have their time set to 23:59:59.
|
190
201
|
def end_of_week(start_day = Date.beginning_of_week)
|
191
|
-
last_hour
|
202
|
+
last_hour(days_since(6 - days_to_week_start(start_day)))
|
192
203
|
end
|
193
204
|
alias :at_end_of_week :end_of_week
|
194
205
|
|
@@ -202,7 +213,7 @@ module DateAndTime
|
|
202
213
|
# DateTime objects will have a time set to 23:59:59.
|
203
214
|
def end_of_month
|
204
215
|
last_day = ::Time.days_in_month(month, year)
|
205
|
-
last_hour
|
216
|
+
last_hour(days_since(last_day - day))
|
206
217
|
end
|
207
218
|
alias :at_end_of_month :end_of_month
|
208
219
|
|
@@ -213,16 +224,35 @@ module DateAndTime
|
|
213
224
|
end
|
214
225
|
alias :at_end_of_year :end_of_year
|
215
226
|
|
227
|
+
# Returns a Range representing the whole week of the current date/time.
|
228
|
+
# Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
|
229
|
+
def all_week(start_day = Date.beginning_of_week)
|
230
|
+
beginning_of_week(start_day)..end_of_week(start_day)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Returns a Range representing the whole month of the current date/time.
|
234
|
+
def all_month
|
235
|
+
beginning_of_month..end_of_month
|
236
|
+
end
|
237
|
+
|
238
|
+
# Returns a Range representing the whole quarter of the current date/time.
|
239
|
+
def all_quarter
|
240
|
+
beginning_of_quarter..end_of_quarter
|
241
|
+
end
|
242
|
+
|
243
|
+
# Returns a Range representing the whole year of the current date/time.
|
244
|
+
def all_year
|
245
|
+
beginning_of_year..end_of_year
|
246
|
+
end
|
247
|
+
|
216
248
|
private
|
217
249
|
|
218
|
-
def first_hour
|
219
|
-
|
220
|
-
acts_like?(:time) ? result.change(:hour => 0) : result
|
250
|
+
def first_hour(date_or_time)
|
251
|
+
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
|
221
252
|
end
|
222
253
|
|
223
|
-
def last_hour
|
224
|
-
|
225
|
-
acts_like?(:time) ? result.end_of_day : result
|
254
|
+
def last_hour(date_or_time)
|
255
|
+
date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
|
226
256
|
end
|
227
257
|
|
228
258
|
def days_span(day)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
require 'active_support/core_ext/module/remove_method'
|
3
|
+
|
4
|
+
module DateAndTime
|
5
|
+
module Compatibility
|
6
|
+
# If true, +to_time+ preserves the timezone offset of receiver.
|
7
|
+
#
|
8
|
+
# NOTE: With Ruby 2.4+ the default for +to_time+ changed from
|
9
|
+
# converting to the local system time, to preserving the offset
|
10
|
+
# of the receiver. For backwards compatibility we're overriding
|
11
|
+
# this behavior, but new apps will have an initializer that sets
|
12
|
+
# this to true, because the new behavior is preferred.
|
13
|
+
mattr_accessor(:preserve_timezone, instance_writer: false) { false }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module DateAndTime
|
2
|
+
module Zones
|
3
|
+
# Returns the simultaneous time in <tt>Time.zone</tt> if a zone is given or
|
4
|
+
# if Time.zone_default is set. Otherwise, it returns the current time.
|
5
|
+
#
|
6
|
+
# Time.zone = 'Hawaii' # => 'Hawaii'
|
7
|
+
# DateTime.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
8
|
+
# Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
|
9
|
+
#
|
10
|
+
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
|
11
|
+
# instead of the operating system's time zone.
|
12
|
+
#
|
13
|
+
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
|
14
|
+
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
15
|
+
#
|
16
|
+
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
17
|
+
# DateTime.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
18
|
+
# Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
|
19
|
+
def in_time_zone(zone = ::Time.zone)
|
20
|
+
time_zone = ::Time.find_zone! zone
|
21
|
+
time = acts_like?(:time) ? self : nil
|
22
|
+
|
23
|
+
if time_zone
|
24
|
+
time_with_zone(time, time_zone)
|
25
|
+
else
|
26
|
+
time || self.to_time
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def time_with_zone(time, zone)
|
33
|
+
if time
|
34
|
+
ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone)
|
35
|
+
else
|
36
|
+
ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -1,14 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'date'
|
2
2
|
|
3
3
|
class DateTime
|
4
4
|
class << self
|
5
|
-
# *DEPRECATED*: Use +DateTime.civil_from_format+ directly.
|
6
|
-
def local_offset
|
7
|
-
ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.'
|
8
|
-
|
9
|
-
::Time.local(2012).utc_offset.to_r / 86400
|
10
|
-
end
|
11
|
-
|
12
5
|
# Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
|
13
6
|
# <tt>config.time_zone</tt> are set, otherwise returns
|
14
7
|
# <tt>Time.now.to_datetime</tt>.
|
@@ -17,16 +10,6 @@ class DateTime
|
|
17
10
|
end
|
18
11
|
end
|
19
12
|
|
20
|
-
# Tells whether the DateTime object's datetime lies in the past.
|
21
|
-
def past?
|
22
|
-
self < ::DateTime.current
|
23
|
-
end
|
24
|
-
|
25
|
-
# Tells whether the DateTime object's datetime lies in the future.
|
26
|
-
def future?
|
27
|
-
self > ::DateTime.current
|
28
|
-
end
|
29
|
-
|
30
13
|
# Seconds since midnight: DateTime.now.seconds_since_midnight.
|
31
14
|
def seconds_since_midnight
|
32
15
|
sec + (min * 60) + (hour * 3600)
|
@@ -41,6 +24,13 @@ class DateTime
|
|
41
24
|
end_of_day.to_i - to_i
|
42
25
|
end
|
43
26
|
|
27
|
+
# Returns the fraction of a second as a +Rational+
|
28
|
+
#
|
29
|
+
# DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
|
30
|
+
def subsec
|
31
|
+
sec_fraction
|
32
|
+
end
|
33
|
+
|
44
34
|
# Returns a new DateTime where one or more of the elements have been changed
|
45
35
|
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
46
36
|
# <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
|
@@ -70,6 +60,16 @@ class DateTime
|
|
70
60
|
# <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
|
71
61
|
# <tt>:minutes</tt>, <tt>:seconds</tt>.
|
72
62
|
def advance(options)
|
63
|
+
unless options[:weeks].nil?
|
64
|
+
options[:weeks], partial_weeks = options[:weeks].divmod(1)
|
65
|
+
options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
|
66
|
+
end
|
67
|
+
|
68
|
+
unless options[:days].nil?
|
69
|
+
options[:days], partial_days = options[:days].divmod(1)
|
70
|
+
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
71
|
+
end
|
72
|
+
|
73
73
|
d = to_date.advance(options)
|
74
74
|
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
|
75
75
|
seconds_to_advance = \
|
@@ -80,7 +80,7 @@ class DateTime
|
|
80
80
|
if seconds_to_advance.zero?
|
81
81
|
datetime_advanced_by_date
|
82
82
|
else
|
83
|
-
datetime_advanced_by_date.since
|
83
|
+
datetime_advanced_by_date.since(seconds_to_advance)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -106,6 +106,16 @@ class DateTime
|
|
106
106
|
alias :at_midnight :beginning_of_day
|
107
107
|
alias :at_beginning_of_day :beginning_of_day
|
108
108
|
|
109
|
+
# Returns a new DateTime representing the middle of the day (12:00)
|
110
|
+
def middle_of_day
|
111
|
+
change(:hour => 12)
|
112
|
+
end
|
113
|
+
alias :midday :middle_of_day
|
114
|
+
alias :noon :middle_of_day
|
115
|
+
alias :at_midday :middle_of_day
|
116
|
+
alias :at_noon :middle_of_day
|
117
|
+
alias :at_middle_of_day :middle_of_day
|
118
|
+
|
109
119
|
# Returns a new DateTime representing the end of the day (23:59:59).
|
110
120
|
def end_of_day
|
111
121
|
change(:hour => 23, :min => 59, :sec => 59)
|
@@ -136,14 +146,27 @@ class DateTime
|
|
136
146
|
end
|
137
147
|
alias :at_end_of_minute :end_of_minute
|
138
148
|
|
139
|
-
#
|
149
|
+
# Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
|
150
|
+
def localtime(utc_offset = nil)
|
151
|
+
utc = new_offset(0)
|
152
|
+
|
153
|
+
Time.utc(
|
154
|
+
utc.year, utc.month, utc.day,
|
155
|
+
utc.hour, utc.min, utc.sec + utc.sec_fraction
|
156
|
+
).getlocal(utc_offset)
|
157
|
+
end
|
158
|
+
alias_method :getlocal, :localtime
|
159
|
+
|
160
|
+
# Returns a <tt>DateTime</tt> instance of the simultaneous time in the UTC timezone.
|
140
161
|
#
|
141
162
|
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
|
142
|
-
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12
|
163
|
+
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
|
143
164
|
def utc
|
144
165
|
new_offset(0)
|
145
166
|
end
|
167
|
+
alias_method :getgm, :utc
|
146
168
|
alias_method :getutc, :utc
|
169
|
+
alias_method :gmtime, :utc
|
147
170
|
|
148
171
|
# Returns +true+ if <tt>offset == 0</tt>.
|
149
172
|
def utc?
|
@@ -161,7 +184,7 @@ class DateTime
|
|
161
184
|
if other.kind_of?(Infinity)
|
162
185
|
super
|
163
186
|
elsif other.respond_to? :to_datetime
|
164
|
-
super other.to_datetime
|
187
|
+
super other.to_datetime rescue nil
|
165
188
|
else
|
166
189
|
nil
|
167
190
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext/date_and_time/compatibility'
|
2
|
+
require 'active_support/core_ext/module/remove_method'
|
3
|
+
|
4
|
+
class DateTime
|
5
|
+
include DateAndTime::Compatibility
|
6
|
+
|
7
|
+
remove_possible_method :to_time
|
8
|
+
|
9
|
+
# Either return an instance of `Time` with the same UTC offset
|
10
|
+
# as +self+ or an instance of `Time` representing the same time
|
11
|
+
# in the the local system timezone depending on the setting of
|
12
|
+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
13
|
+
def to_time
|
14
|
+
preserve_timezone ? getlocal(utc_offset) : getlocal
|
15
|
+
end
|
16
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'date'
|
1
2
|
require 'active_support/inflector/methods'
|
2
3
|
require 'active_support/core_ext/time/conversions'
|
3
4
|
require 'active_support/core_ext/date_time/calculations'
|
@@ -18,6 +19,7 @@ class DateTime
|
|
18
19
|
# datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
|
19
20
|
# datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
|
20
21
|
# datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
22
|
+
# datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
|
21
23
|
#
|
22
24
|
# == Adding your own datetime formats to to_formatted_s
|
23
25
|
# DateTime formats are shared with Time. You can add your own to the
|
@@ -69,9 +71,9 @@ class DateTime
|
|
69
71
|
civil(year, month, day, hour, min, sec, offset)
|
70
72
|
end
|
71
73
|
|
72
|
-
# Converts +self+ to a floating-point number of seconds since the Unix epoch.
|
74
|
+
# Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
|
73
75
|
def to_f
|
74
|
-
seconds_since_unix_epoch.to_f
|
76
|
+
seconds_since_unix_epoch.to_f + sec_fraction
|
75
77
|
end
|
76
78
|
|
77
79
|
# Converts +self+ to an integer number of seconds since the Unix epoch.
|
@@ -1,24 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'date'
|
2
|
+
require 'active_support/core_ext/date_and_time/zones'
|
2
3
|
|
3
4
|
class DateTime
|
4
|
-
|
5
|
-
#
|
6
|
-
# Time.zone = 'Hawaii' # => 'Hawaii'
|
7
|
-
# DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
8
|
-
#
|
9
|
-
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt>
|
10
|
-
# as the local zone instead of the operating system's time zone.
|
11
|
-
#
|
12
|
-
# You can also pass in a TimeZone instance or string that identifies a TimeZone
|
13
|
-
# as an argument, and the conversion will be based on that zone instead of
|
14
|
-
# <tt>Time.zone</tt>.
|
15
|
-
#
|
16
|
-
# DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
17
|
-
def in_time_zone(zone = ::Time.zone)
|
18
|
-
if zone
|
19
|
-
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
|
20
|
-
else
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
5
|
+
include DateAndTime::Zones
|
24
6
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/date_time/acts_like'
|
2
2
|
require 'active_support/core_ext/date_time/calculations'
|
3
|
+
require 'active_support/core_ext/date_time/compatibility'
|
3
4
|
require 'active_support/core_ext/date_time/conversions'
|
4
5
|
require 'active_support/core_ext/date_time/zones'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Digest
|
4
|
+
module UUID
|
5
|
+
DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
6
|
+
URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
7
|
+
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
8
|
+
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
9
|
+
|
10
|
+
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
11
|
+
#
|
12
|
+
# Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
|
13
|
+
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
14
|
+
#
|
15
|
+
# See RFC 4122 for details of UUID at: http://www.ietf.org/rfc/rfc4122.txt
|
16
|
+
def self.uuid_from_hash(hash_class, uuid_namespace, name)
|
17
|
+
if hash_class == Digest::MD5
|
18
|
+
version = 3
|
19
|
+
elsif hash_class == Digest::SHA1
|
20
|
+
version = 5
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
|
23
|
+
end
|
24
|
+
|
25
|
+
hash = hash_class.new
|
26
|
+
hash.update(uuid_namespace)
|
27
|
+
hash.update(name)
|
28
|
+
|
29
|
+
ary = hash.digest.unpack('NnnnnN')
|
30
|
+
ary[2] = (ary[2] & 0x0FFF) | (version << 12)
|
31
|
+
ary[3] = (ary[3] & 0x3FFF) | 0x8000
|
32
|
+
|
33
|
+
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
34
|
+
end
|
35
|
+
|
36
|
+
# Convenience method for uuid_from_hash using Digest::MD5.
|
37
|
+
def self.uuid_v3(uuid_namespace, name)
|
38
|
+
self.uuid_from_hash(Digest::MD5, uuid_namespace, name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convenience method for uuid_from_hash using Digest::SHA1.
|
42
|
+
def self.uuid_v5(uuid_namespace, name)
|
43
|
+
self.uuid_from_hash(Digest::SHA1, uuid_namespace, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Convenience method for SecureRandom.uuid.
|
47
|
+
def self.uuid_v4
|
48
|
+
SecureRandom.uuid
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -35,7 +35,7 @@ module Enumerable
|
|
35
35
|
if block_given?
|
36
36
|
Hash[map { |elem| [yield(elem), elem] }]
|
37
37
|
else
|
38
|
-
to_enum :
|
38
|
+
to_enum(:index_by) { size if respond_to?(:size) }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -78,3 +78,19 @@ class Range #:nodoc:
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
# Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
|
83
|
+
#
|
84
|
+
# We tried shimming it to attempt the fast native method, rescue TypeError,
|
85
|
+
# and fall back to the compatible implementation, but that's much slower than
|
86
|
+
# just calling the compat method in the first place.
|
87
|
+
if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
|
88
|
+
class Array
|
89
|
+
remove_method :sum
|
90
|
+
|
91
|
+
def sum(*args) #:nodoc:
|
92
|
+
# Use Enumerable#sum instead.
|
93
|
+
super
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -40,7 +40,7 @@ class File
|
|
40
40
|
chown(old_stat.uid, old_stat.gid, file_name)
|
41
41
|
# This operation will affect filesystem ACL's
|
42
42
|
chmod(old_stat.mode, file_name)
|
43
|
-
rescue Errno::EPERM
|
43
|
+
rescue Errno::EPERM, Errno::EACCES
|
44
44
|
# Changing file ownership failed, moving on.
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Hash
|
2
|
+
unless Hash.instance_methods(false).include?(:compact)
|
3
|
+
# Returns a hash with non +nil+ values.
|
4
|
+
#
|
5
|
+
# hash = { a: true, b: false, c: nil}
|
6
|
+
# hash.compact # => { a: true, b: false}
|
7
|
+
# hash # => { a: true, b: false, c: nil}
|
8
|
+
# { c: nil }.compact # => {}
|
9
|
+
def compact
|
10
|
+
self.select { |_, value| !value.nil? }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
unless Hash.instance_methods(false).include?(:compact!)
|
15
|
+
# Replaces current hash with non +nil+ values.
|
16
|
+
#
|
17
|
+
# hash = { a: true, b: false, c: nil}
|
18
|
+
# hash.compact! # => { a: true, b: false}
|
19
|
+
# hash # => { a: true, b: false}
|
20
|
+
def compact!
|
21
|
+
self.reject! { |_, value| value.nil? }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -10,7 +10,7 @@ require 'active_support/core_ext/string/inflections'
|
|
10
10
|
class Hash
|
11
11
|
# Returns a string containing an XML representation of its receiver:
|
12
12
|
#
|
13
|
-
# {
|
13
|
+
# { foo: 1, bar: 2 }.to_xml
|
14
14
|
# # =>
|
15
15
|
# # <?xml version="1.0" encoding="UTF-8"?>
|
16
16
|
# # <hash>
|
@@ -43,7 +43,10 @@ class Hash
|
|
43
43
|
# end
|
44
44
|
#
|
45
45
|
# { foo: Foo.new }.to_xml(skip_instruct: true)
|
46
|
-
# # =>
|
46
|
+
# # =>
|
47
|
+
# # <hash>
|
48
|
+
# # <bar>fooing!</bar>
|
49
|
+
# # </hash>
|
47
50
|
#
|
48
51
|
# * Otherwise, a node with +key+ as tag is created with a string representation of
|
49
52
|
# +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added.
|
@@ -52,8 +55,7 @@ class Hash
|
|
52
55
|
#
|
53
56
|
# XML_TYPE_NAMES = {
|
54
57
|
# "Symbol" => "symbol",
|
55
|
-
# "
|
56
|
-
# "Bignum" => "integer",
|
58
|
+
# "Integer" => "integer",
|
57
59
|
# "BigDecimal" => "decimal",
|
58
60
|
# "Float" => "float",
|
59
61
|
# "TrueClass" => "boolean",
|
@@ -102,7 +104,7 @@ class Hash
|
|
102
104
|
# hash = Hash.from_xml(xml)
|
103
105
|
# # => {"hash"=>{"foo"=>1, "bar"=>2}}
|
104
106
|
#
|
105
|
-
# DisallowedType is
|
107
|
+
# +DisallowedType+ is raised if the XML contains attributes with <tt>type="yaml"</tt> or
|
106
108
|
# <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
|
107
109
|
def from_xml(xml, disallowed_types = nil)
|
108
110
|
ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
|
@@ -201,7 +203,7 @@ module ActiveSupport
|
|
201
203
|
end
|
202
204
|
|
203
205
|
def become_empty_string?(value)
|
204
|
-
# {"string" => true}
|
206
|
+
# { "string" => true }
|
205
207
|
# No tests fail when the second term is removed.
|
206
208
|
value['type'] == 'string' && value['nil'] != 'true'
|
207
209
|
end
|
@@ -218,7 +220,7 @@ module ActiveSupport
|
|
218
220
|
def garbage?(value)
|
219
221
|
# If the type is the only element which makes it then
|
220
222
|
# this still makes the value nil, except if type is
|
221
|
-
#
|
223
|
+
# an XML node(where type['value'] is a Hash)
|
222
224
|
value['type'] && !value['type'].is_a?(::Hash) && value.size == 1
|
223
225
|
end
|
224
226
|
|
@@ -238,4 +240,3 @@ module ActiveSupport
|
|
238
240
|
|
239
241
|
end
|
240
242
|
end
|
241
|
-
|
@@ -1,13 +1,19 @@
|
|
1
1
|
class Hash
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Returns a hash that includes everything but the given keys.
|
3
|
+
# hash = { a: true, b: false, c: nil}
|
4
|
+
# hash.except(:c) # => { a: true, b: false}
|
5
|
+
# hash # => { a: true, b: false, c: nil}
|
4
6
|
#
|
7
|
+
# This is useful for limiting a set of parameters to everything but a few known toggles:
|
5
8
|
# @person.update(params[:person].except(:admin))
|
6
9
|
def except(*keys)
|
7
10
|
dup.except!(*keys)
|
8
11
|
end
|
9
12
|
|
10
13
|
# Replaces the hash without the given keys.
|
14
|
+
# hash = { a: true, b: false, c: nil}
|
15
|
+
# hash.except!(:c) # => { a: true, b: false}
|
16
|
+
# hash # => { a: true, b: false }
|
11
17
|
def except!(*keys)
|
12
18
|
keys.each { |key| delete(key) }
|
13
19
|
self
|