activesupport 3.2.22.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache/file_store.rb +14 -14
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +21 -0
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +92 -49
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +8 -7
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +127 -42
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/subscriber.rb +93 -0
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +54 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +29 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
|
@@ -1,46 +1,67 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'active_support/deprecation'
|
|
2
2
|
|
|
3
3
|
class DateTime
|
|
4
4
|
class << self
|
|
5
|
-
#
|
|
5
|
+
# *DEPRECATED*: Use +DateTime.civil_from_format+ directly.
|
|
6
6
|
def local_offset
|
|
7
|
+
ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.'
|
|
8
|
+
|
|
7
9
|
::Time.local(2012).utc_offset.to_r / 86400
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
# Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
|
|
12
|
+
# Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
|
|
13
|
+
# <tt>config.time_zone</tt> are set, otherwise returns
|
|
14
|
+
# <tt>Time.now.to_datetime</tt>.
|
|
11
15
|
def current
|
|
12
16
|
::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
|
|
13
17
|
end
|
|
14
18
|
end
|
|
15
19
|
|
|
16
|
-
# Tells whether the DateTime object's datetime lies in the past
|
|
20
|
+
# Tells whether the DateTime object's datetime lies in the past.
|
|
17
21
|
def past?
|
|
18
22
|
self < ::DateTime.current
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
# Tells whether the DateTime object's datetime lies in the future
|
|
25
|
+
# Tells whether the DateTime object's datetime lies in the future.
|
|
22
26
|
def future?
|
|
23
27
|
self > ::DateTime.current
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
# Seconds since midnight: DateTime.now.seconds_since_midnight
|
|
30
|
+
# Seconds since midnight: DateTime.now.seconds_since_midnight.
|
|
27
31
|
def seconds_since_midnight
|
|
28
32
|
sec + (min * 60) + (hour * 3600)
|
|
29
33
|
end
|
|
30
34
|
|
|
31
|
-
# Returns
|
|
32
|
-
#
|
|
33
|
-
#
|
|
35
|
+
# Returns the number of seconds until 23:59:59.
|
|
36
|
+
#
|
|
37
|
+
# DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
|
|
38
|
+
# DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
|
|
39
|
+
# DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
|
|
40
|
+
def seconds_until_end_of_day
|
|
41
|
+
end_of_day.to_i - to_i
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns a new DateTime where one or more of the elements have been changed
|
|
45
|
+
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
|
46
|
+
# <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
|
|
47
|
+
# passed, then minute and sec is set to 0. If the hour and minute is passed,
|
|
48
|
+
# then sec is set to 0. The +options+ parameter takes a hash with any of these
|
|
49
|
+
# keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
|
|
50
|
+
# <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
|
|
51
|
+
#
|
|
52
|
+
# DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)
|
|
53
|
+
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
|
|
54
|
+
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
|
|
34
55
|
def change(options)
|
|
35
56
|
::DateTime.civil(
|
|
36
|
-
options
|
|
37
|
-
options
|
|
38
|
-
options
|
|
39
|
-
options
|
|
40
|
-
options
|
|
41
|
-
options
|
|
42
|
-
options
|
|
43
|
-
options
|
|
57
|
+
options.fetch(:year, year),
|
|
58
|
+
options.fetch(:month, month),
|
|
59
|
+
options.fetch(:day, day),
|
|
60
|
+
options.fetch(:hour, hour),
|
|
61
|
+
options.fetch(:min, options[:hour] ? 0 : min),
|
|
62
|
+
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec + sec_fraction),
|
|
63
|
+
options.fetch(:offset, offset),
|
|
64
|
+
options.fetch(:start, start)
|
|
44
65
|
)
|
|
45
66
|
end
|
|
46
67
|
|
|
@@ -51,24 +72,33 @@ class DateTime
|
|
|
51
72
|
def advance(options)
|
|
52
73
|
d = to_date.advance(options)
|
|
53
74
|
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
|
|
54
|
-
seconds_to_advance =
|
|
55
|
-
|
|
75
|
+
seconds_to_advance = \
|
|
76
|
+
options.fetch(:seconds, 0) +
|
|
77
|
+
options.fetch(:minutes, 0) * 60 +
|
|
78
|
+
options.fetch(:hours, 0) * 3600
|
|
79
|
+
|
|
80
|
+
if seconds_to_advance.zero?
|
|
81
|
+
datetime_advanced_by_date
|
|
82
|
+
else
|
|
83
|
+
datetime_advanced_by_date.since seconds_to_advance
|
|
84
|
+
end
|
|
56
85
|
end
|
|
57
86
|
|
|
58
|
-
# Returns a new DateTime representing the time a number of seconds ago
|
|
87
|
+
# Returns a new DateTime representing the time a number of seconds ago.
|
|
59
88
|
# Do not use this method in combination with x.months, use months_ago instead!
|
|
60
89
|
def ago(seconds)
|
|
61
90
|
since(-seconds)
|
|
62
91
|
end
|
|
63
92
|
|
|
64
|
-
# Returns a new DateTime representing the time a number of seconds since the
|
|
65
|
-
# Do not use this method in combination with x.months, use
|
|
93
|
+
# Returns a new DateTime representing the time a number of seconds since the
|
|
94
|
+
# instance time. Do not use this method in combination with x.months, use
|
|
95
|
+
# months_since instead!
|
|
66
96
|
def since(seconds)
|
|
67
97
|
self + Rational(seconds.round, 86400)
|
|
68
98
|
end
|
|
69
99
|
alias :in :since
|
|
70
100
|
|
|
71
|
-
# Returns a new DateTime representing the start of the day (0:00)
|
|
101
|
+
# Returns a new DateTime representing the start of the day (0:00).
|
|
72
102
|
def beginning_of_day
|
|
73
103
|
change(:hour => 0)
|
|
74
104
|
end
|
|
@@ -76,74 +106,59 @@ class DateTime
|
|
|
76
106
|
alias :at_midnight :beginning_of_day
|
|
77
107
|
alias :at_beginning_of_day :beginning_of_day
|
|
78
108
|
|
|
79
|
-
# Returns a new DateTime representing the end of the day (23:59:59)
|
|
109
|
+
# Returns a new DateTime representing the end of the day (23:59:59).
|
|
80
110
|
def end_of_day
|
|
81
111
|
change(:hour => 23, :min => 59, :sec => 59)
|
|
82
112
|
end
|
|
113
|
+
alias :at_end_of_day :end_of_day
|
|
83
114
|
|
|
84
|
-
# Returns a new DateTime representing the start of the hour (hh:00:00)
|
|
115
|
+
# Returns a new DateTime representing the start of the hour (hh:00:00).
|
|
85
116
|
def beginning_of_hour
|
|
86
117
|
change(:min => 0)
|
|
87
118
|
end
|
|
88
119
|
alias :at_beginning_of_hour :beginning_of_hour
|
|
89
120
|
|
|
90
|
-
# Returns a new DateTime representing the end of the hour (hh:59:59)
|
|
121
|
+
# Returns a new DateTime representing the end of the hour (hh:59:59).
|
|
91
122
|
def end_of_hour
|
|
92
123
|
change(:min => 59, :sec => 59)
|
|
93
124
|
end
|
|
125
|
+
alias :at_end_of_hour :end_of_hour
|
|
94
126
|
|
|
95
|
-
#
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if ActiveSupport::Duration === other
|
|
99
|
-
other.since(self)
|
|
100
|
-
else
|
|
101
|
-
plus_without_duration(other)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
alias_method :plus_without_duration, :+
|
|
105
|
-
alias_method :+, :plus_with_duration
|
|
106
|
-
|
|
107
|
-
def minus_with_duration(other) #:nodoc:
|
|
108
|
-
if ActiveSupport::Duration === other
|
|
109
|
-
plus_with_duration(-other)
|
|
110
|
-
else
|
|
111
|
-
minus_without_duration(other)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
alias_method :minus_without_duration, :-
|
|
115
|
-
alias_method :-, :minus_with_duration
|
|
127
|
+
# Returns a new DateTime representing the start of the minute (hh:mm:00).
|
|
128
|
+
def beginning_of_minute
|
|
129
|
+
change(:sec => 0)
|
|
116
130
|
end
|
|
131
|
+
alias :at_beginning_of_minute :beginning_of_minute
|
|
117
132
|
|
|
118
|
-
#
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
# Returns a new DateTime representing the end of the minute (hh:mm:59).
|
|
134
|
+
def end_of_minute
|
|
135
|
+
change(:sec => 59)
|
|
136
|
+
end
|
|
137
|
+
alias :at_end_of_minute :end_of_minute
|
|
138
|
+
|
|
139
|
+
# Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
|
|
121
140
|
#
|
|
122
|
-
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))
|
|
123
|
-
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc
|
|
141
|
+
# 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 +0000
|
|
124
143
|
def utc
|
|
125
144
|
new_offset(0)
|
|
126
145
|
end
|
|
127
146
|
alias_method :getutc, :utc
|
|
128
147
|
|
|
129
|
-
# Returns true if offset == 0
|
|
148
|
+
# Returns +true+ if <tt>offset == 0</tt>.
|
|
130
149
|
def utc?
|
|
131
150
|
offset == 0
|
|
132
151
|
end
|
|
133
152
|
|
|
134
|
-
# Returns the offset value in seconds
|
|
153
|
+
# Returns the offset value in seconds.
|
|
135
154
|
def utc_offset
|
|
136
155
|
(offset * 86400).to_i
|
|
137
156
|
end
|
|
138
157
|
|
|
139
|
-
# Layers additional behavior on DateTime#<=> so that Time and
|
|
158
|
+
# Layers additional behavior on DateTime#<=> so that Time and
|
|
159
|
+
# ActiveSupport::TimeWithZone instances can be compared with a DateTime.
|
|
140
160
|
def <=>(other)
|
|
141
|
-
|
|
142
|
-
super
|
|
143
|
-
elsif other.respond_to? :to_datetime
|
|
144
|
-
super other.to_datetime
|
|
145
|
-
else
|
|
146
|
-
nil
|
|
147
|
-
end
|
|
161
|
+
super other.to_datetime
|
|
148
162
|
end
|
|
163
|
+
|
|
149
164
|
end
|
|
@@ -4,10 +4,6 @@ require 'active_support/core_ext/date_time/calculations'
|
|
|
4
4
|
require 'active_support/values/time_zone'
|
|
5
5
|
|
|
6
6
|
class DateTime
|
|
7
|
-
# Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows
|
|
8
|
-
# DateTimes outside the range of what can be created with Time.
|
|
9
|
-
remove_method :to_time if instance_methods.include?(:to_time)
|
|
10
|
-
|
|
11
7
|
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
|
12
8
|
#
|
|
13
9
|
# This method is aliased to <tt>to_s</tt>.
|
|
@@ -30,7 +26,7 @@ class DateTime
|
|
|
30
26
|
# datetime argument as the value.
|
|
31
27
|
#
|
|
32
28
|
# # config/initializers/time_formats.rb
|
|
33
|
-
# Time::DATE_FORMATS[:month_and_year] =
|
|
29
|
+
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
|
34
30
|
# Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
|
|
35
31
|
def to_formatted_s(format = :default)
|
|
36
32
|
if formatter = ::Time::DATE_FORMATS[format]
|
|
@@ -39,10 +35,9 @@ class DateTime
|
|
|
39
35
|
to_default_s
|
|
40
36
|
end
|
|
41
37
|
end
|
|
42
|
-
alias_method :to_default_s, :to_s
|
|
38
|
+
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
|
43
39
|
alias_method :to_s, :to_formatted_s
|
|
44
40
|
|
|
45
|
-
# Returns the +utc_offset+ as an +HH:MM formatted string. Examples:
|
|
46
41
|
#
|
|
47
42
|
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
|
48
43
|
# datetime.formatted_offset # => "-06:00"
|
|
@@ -58,46 +53,39 @@ class DateTime
|
|
|
58
53
|
alias_method :default_inspect, :inspect
|
|
59
54
|
alias_method :inspect, :readable_inspect
|
|
60
55
|
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
def to_time
|
|
69
|
-
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * (RUBY_VERSION < '1.9' ? 86400000000 : 1000000)) : self
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# To be able to keep Times, Dates and DateTimes interchangeable on conversions.
|
|
73
|
-
def to_datetime
|
|
74
|
-
self
|
|
75
|
-
end unless instance_methods(false).include?(:to_datetime)
|
|
76
|
-
|
|
56
|
+
# Returns DateTime with local offset for given year if format is local else
|
|
57
|
+
# offset is zero.
|
|
58
|
+
#
|
|
59
|
+
# DateTime.civil_from_format :local, 2012
|
|
60
|
+
# # => Sun, 01 Jan 2012 00:00:00 +0300
|
|
61
|
+
# DateTime.civil_from_format :local, 2012, 12, 17
|
|
62
|
+
# # => Mon, 17 Dec 2012 00:00:00 +0000
|
|
77
63
|
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
|
|
78
|
-
|
|
64
|
+
if utc_or_local.to_sym == :local
|
|
65
|
+
offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
|
|
66
|
+
else
|
|
67
|
+
offset = 0
|
|
68
|
+
end
|
|
79
69
|
civil(year, month, day, hour, min, sec, offset)
|
|
80
70
|
end
|
|
81
71
|
|
|
82
|
-
# Converts
|
|
83
|
-
def xmlschema
|
|
84
|
-
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
|
85
|
-
end unless instance_methods(false).include?(:xmlschema)
|
|
86
|
-
|
|
87
|
-
# Converts self to a floating-point number of seconds since the Unix epoch.
|
|
72
|
+
# Converts +self+ to a floating-point number of seconds since the Unix epoch.
|
|
88
73
|
def to_f
|
|
89
74
|
seconds_since_unix_epoch.to_f
|
|
90
75
|
end
|
|
91
76
|
|
|
92
|
-
# Converts self to an integer number of seconds since the Unix epoch.
|
|
77
|
+
# Converts +self+ to an integer number of seconds since the Unix epoch.
|
|
93
78
|
def to_i
|
|
94
79
|
seconds_since_unix_epoch.to_i
|
|
95
80
|
end
|
|
96
81
|
|
|
97
82
|
private
|
|
98
83
|
|
|
84
|
+
def offset_in_seconds
|
|
85
|
+
(offset * 86400).to_i
|
|
86
|
+
end
|
|
87
|
+
|
|
99
88
|
def seconds_since_unix_epoch
|
|
100
|
-
|
|
101
|
-
(self - ::DateTime.civil(1970)) * seconds_per_day
|
|
89
|
+
(jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
|
|
102
90
|
end
|
|
103
91
|
end
|
|
@@ -6,16 +6,19 @@ class DateTime
|
|
|
6
6
|
# Time.zone = 'Hawaii' # => 'Hawaii'
|
|
7
7
|
# DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
|
8
8
|
#
|
|
9
|
-
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt>
|
|
10
|
-
# instead of the operating system's time zone.
|
|
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
11
|
#
|
|
12
|
-
# You can also pass in a TimeZone instance or string that identifies a TimeZone
|
|
13
|
-
# and the conversion will be based on that zone instead of
|
|
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>.
|
|
14
15
|
#
|
|
15
|
-
# DateTime.new(2000).in_time_zone('Alaska')
|
|
16
|
+
# DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
|
16
17
|
def in_time_zone(zone = ::Time.zone)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
if zone
|
|
19
|
+
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
|
|
20
|
+
else
|
|
21
|
+
self
|
|
22
|
+
end
|
|
20
23
|
end
|
|
21
24
|
end
|
|
@@ -1,42 +1,5 @@
|
|
|
1
|
-
require 'active_support/ordered_hash'
|
|
2
|
-
|
|
3
1
|
module Enumerable
|
|
4
|
-
#
|
|
5
|
-
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
|
|
6
|
-
|
|
7
|
-
# Collect an enumerable into sets, grouped by the result of a block. Useful,
|
|
8
|
-
# for example, for grouping records by date.
|
|
9
|
-
#
|
|
10
|
-
# Example:
|
|
11
|
-
#
|
|
12
|
-
# latest_transcripts.group_by(&:day).each do |day, transcripts|
|
|
13
|
-
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
|
|
14
|
-
# end
|
|
15
|
-
# "2006-03-01 -> Transcript"
|
|
16
|
-
# "2006-02-28 -> Transcript"
|
|
17
|
-
# "2006-02-27 -> Transcript, Transcript"
|
|
18
|
-
# "2006-02-26 -> Transcript, Transcript"
|
|
19
|
-
# "2006-02-25 -> Transcript"
|
|
20
|
-
# "2006-02-24 -> Transcript, Transcript"
|
|
21
|
-
# "2006-02-23 -> Transcript"
|
|
22
|
-
def group_by
|
|
23
|
-
return to_enum :group_by unless block_given?
|
|
24
|
-
assoc = ActiveSupport::OrderedHash.new
|
|
25
|
-
|
|
26
|
-
each do |element|
|
|
27
|
-
key = yield(element)
|
|
28
|
-
|
|
29
|
-
if assoc.has_key?(key)
|
|
30
|
-
assoc[key] << element
|
|
31
|
-
else
|
|
32
|
-
assoc[key] = [element]
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
assoc
|
|
37
|
-
end unless [].respond_to?(:group_by)
|
|
38
|
-
|
|
39
|
-
# Calculates a sum from the elements. Examples:
|
|
2
|
+
# Calculates a sum from the elements.
|
|
40
3
|
#
|
|
41
4
|
# payments.sum { |p| p.price * p.tax_rate }
|
|
42
5
|
# payments.sum(&:price)
|
|
@@ -48,56 +11,38 @@ module Enumerable
|
|
|
48
11
|
# It can also calculate the sum without the use of a block.
|
|
49
12
|
#
|
|
50
13
|
# [5, 15, 10].sum # => 30
|
|
51
|
-
# [
|
|
14
|
+
# ['foo', 'bar'].sum # => "foobar"
|
|
52
15
|
# [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
|
|
53
16
|
#
|
|
54
17
|
# The default sum of an empty list is zero. You can override this default:
|
|
55
18
|
#
|
|
56
19
|
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
|
57
|
-
#
|
|
58
20
|
def sum(identity = 0, &block)
|
|
59
21
|
if block_given?
|
|
60
22
|
map(&block).sum(identity)
|
|
61
23
|
else
|
|
62
|
-
inject
|
|
24
|
+
inject { |sum, element| sum + element } || identity
|
|
63
25
|
end
|
|
64
26
|
end
|
|
65
27
|
|
|
66
|
-
#
|
|
67
|
-
# +memo+ to the block. Handy for building up hashes or
|
|
68
|
-
# reducing collections down to one object. Examples:
|
|
69
|
-
#
|
|
70
|
-
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
|
|
71
|
-
# # => {'foo' => 'FOO', 'bar' => 'BAR'}
|
|
72
|
-
#
|
|
73
|
-
# *Note* that you can't use immutable objects like numbers, true or false as
|
|
74
|
-
# the memo. You would think the following returns 120, but since the memo is
|
|
75
|
-
# never changed, it does not.
|
|
76
|
-
#
|
|
77
|
-
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
|
|
78
|
-
#
|
|
79
|
-
def each_with_object(memo)
|
|
80
|
-
return to_enum :each_with_object, memo unless block_given?
|
|
81
|
-
each do |element|
|
|
82
|
-
yield element, memo
|
|
83
|
-
end
|
|
84
|
-
memo
|
|
85
|
-
end unless [].respond_to?(:each_with_object)
|
|
86
|
-
|
|
87
|
-
# Convert an enumerable to a hash. Examples:
|
|
28
|
+
# Convert an enumerable to a hash.
|
|
88
29
|
#
|
|
89
30
|
# people.index_by(&:login)
|
|
90
31
|
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
|
|
91
32
|
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
|
|
92
33
|
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
|
|
93
|
-
#
|
|
94
34
|
def index_by
|
|
95
|
-
|
|
96
|
-
|
|
35
|
+
if block_given?
|
|
36
|
+
Hash[map { |elem| [yield(elem), elem] }]
|
|
37
|
+
else
|
|
38
|
+
to_enum :index_by
|
|
39
|
+
end
|
|
97
40
|
end
|
|
98
41
|
|
|
99
|
-
# Returns true if the enumerable has more than 1 element. Functionally
|
|
100
|
-
#
|
|
42
|
+
# Returns +true+ if the enumerable has more than 1 element. Functionally
|
|
43
|
+
# equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
|
|
44
|
+
# much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
|
|
45
|
+
# if more than one person is over 26.
|
|
101
46
|
def many?
|
|
102
47
|
cnt = 0
|
|
103
48
|
if block_given?
|
|
@@ -106,11 +51,12 @@ module Enumerable
|
|
|
106
51
|
cnt > 1
|
|
107
52
|
end
|
|
108
53
|
else
|
|
109
|
-
any?{ (cnt += 1) > 1 }
|
|
54
|
+
any? { (cnt += 1) > 1 }
|
|
110
55
|
end
|
|
111
56
|
end
|
|
112
57
|
|
|
113
|
-
# The negative of the <tt>Enumerable#include?</tt>. Returns true if the
|
|
58
|
+
# The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
|
|
59
|
+
# collection does not include the object.
|
|
114
60
|
def exclude?(object)
|
|
115
61
|
!include?(object)
|
|
116
62
|
end
|
|
@@ -120,8 +66,15 @@ class Range #:nodoc:
|
|
|
120
66
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
|
121
67
|
# we have a range of numeric values.
|
|
122
68
|
def sum(identity = 0)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
69
|
+
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
|
|
70
|
+
super
|
|
71
|
+
else
|
|
72
|
+
actual_last = exclude_end? ? (last - 1) : last
|
|
73
|
+
if actual_last >= first
|
|
74
|
+
(actual_last - first + 1) * (actual_last + first) / 2
|
|
75
|
+
else
|
|
76
|
+
identity
|
|
77
|
+
end
|
|
78
|
+
end
|
|
126
79
|
end
|
|
127
80
|
end
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
1
3
|
class File
|
|
2
4
|
# Write to a file atomically. Useful for situations where you don't
|
|
3
5
|
# want other processes or threads to see half-written files.
|
|
4
6
|
#
|
|
5
|
-
# File.atomic_write(
|
|
6
|
-
# file.write(
|
|
7
|
+
# File.atomic_write('important.file') do |file|
|
|
8
|
+
# file.write('hello')
|
|
7
9
|
# end
|
|
8
10
|
#
|
|
9
11
|
# If your temp directory is not on the same filesystem as the file you're
|
|
10
12
|
# trying to write, you can provide a different temporary directory.
|
|
11
13
|
#
|
|
12
|
-
# File.atomic_write(
|
|
13
|
-
# file.write(
|
|
14
|
+
# File.atomic_write('/data/something.important', '/data/tmp') do |file|
|
|
15
|
+
# file.write('hello')
|
|
14
16
|
# end
|
|
15
17
|
def self.atomic_write(file_name, temp_dir = Dir.tmpdir)
|
|
16
18
|
require 'tempfile' unless defined?(Tempfile)
|
|
@@ -21,15 +23,13 @@ class File
|
|
|
21
23
|
yield temp_file
|
|
22
24
|
temp_file.close
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
if File.exists?(file_name)
|
|
25
27
|
# Get original file permissions
|
|
26
28
|
old_stat = stat(file_name)
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
old_stat = stat(check_name)
|
|
32
|
-
unlink(check_name)
|
|
29
|
+
else
|
|
30
|
+
# If not possible, probe which are the default permissions in the
|
|
31
|
+
# destination directory.
|
|
32
|
+
old_stat = probe_stat_in(dirname(file_name))
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# Overwrite original file with temp file
|
|
@@ -44,4 +44,20 @@ class File
|
|
|
44
44
|
# Changing file ownership failed, moving on.
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
# Private utility method.
|
|
49
|
+
def self.probe_stat_in(dir) #:nodoc:
|
|
50
|
+
basename = [
|
|
51
|
+
'.permissions_check',
|
|
52
|
+
Thread.current.object_id,
|
|
53
|
+
Process.pid,
|
|
54
|
+
rand(1000000)
|
|
55
|
+
].join('.')
|
|
56
|
+
|
|
57
|
+
file_name = join(dir, basename)
|
|
58
|
+
FileUtils.touch(file_name)
|
|
59
|
+
stat(file_name)
|
|
60
|
+
ensure
|
|
61
|
+
FileUtils.rm_f(file_name) if file_name
|
|
62
|
+
end
|
|
47
63
|
end
|