activesupport 3.2.22.5 → 4.0.0.beta1
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 +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- 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.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- 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/callbacks.rb +195 -247
- 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.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -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 +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- 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.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.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/infinite_comparable.rb +35 -0
- 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 +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- 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 +57 -40
- 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/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.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 +6 -6
- 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/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -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/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- 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/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- 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/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 +112 -37
- 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.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- 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/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 +52 -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 +25 -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 +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- 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.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- 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.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- 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/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.rb +0 -317
- 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.rb +0 -152
- 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/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -5,25 +5,27 @@ require 'active_support/core_ext/module/remove_method'
|
|
5
5
|
|
6
6
|
class Date
|
7
7
|
DATE_FORMATS = {
|
8
|
-
:short =>
|
9
|
-
:long =>
|
10
|
-
:db =>
|
11
|
-
:number =>
|
12
|
-
:long_ordinal => lambda { |date|
|
13
|
-
|
8
|
+
:short => '%e %b',
|
9
|
+
:long => '%B %e, %Y',
|
10
|
+
:db => '%Y-%m-%d',
|
11
|
+
:number => '%Y%m%d',
|
12
|
+
:long_ordinal => lambda { |date|
|
13
|
+
day_format = ActiveSupport::Inflector.ordinalize(date.day)
|
14
|
+
date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007"
|
15
|
+
},
|
16
|
+
:rfc822 => '%e %b %Y'
|
14
17
|
}
|
15
18
|
|
16
19
|
# Ruby 1.9 has Date#to_time which converts to localtime only.
|
17
|
-
|
20
|
+
remove_method :to_time
|
18
21
|
|
19
22
|
# Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
|
20
|
-
|
23
|
+
remove_method :xmlschema
|
21
24
|
|
22
25
|
# Convert to a formatted string. See DATE_FORMATS for predefined formats.
|
23
26
|
#
|
24
27
|
# This method is aliased to <tt>to_s</tt>.
|
25
28
|
#
|
26
|
-
# ==== Examples
|
27
29
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
28
30
|
#
|
29
31
|
# date.to_formatted_s(:db) # => "2007-11-10"
|
@@ -40,8 +42,8 @@ class Date
|
|
40
42
|
# or Proc instance that takes a date argument as the value.
|
41
43
|
#
|
42
44
|
# # config/initializers/time_formats.rb
|
43
|
-
# Date::DATE_FORMATS[:month_and_year] =
|
44
|
-
# Date::DATE_FORMATS[:short_ordinal] =
|
45
|
+
# Date::DATE_FORMATS[:month_and_year] = '%B %Y'
|
46
|
+
# Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
|
45
47
|
def to_formatted_s(format = :default)
|
46
48
|
if formatter = DATE_FORMATS[format]
|
47
49
|
if formatter.respond_to?(:call)
|
@@ -58,21 +60,14 @@ class Date
|
|
58
60
|
|
59
61
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
60
62
|
def readable_inspect
|
61
|
-
strftime(
|
63
|
+
strftime('%a, %d %b %Y')
|
62
64
|
end
|
63
65
|
alias_method :default_inspect, :inspect
|
64
66
|
alias_method :inspect, :readable_inspect
|
65
67
|
|
66
|
-
# A method to keep Time, Date and DateTime instances interchangeable on conversions.
|
67
|
-
# In this case, it simply returns +self+.
|
68
|
-
def to_date
|
69
|
-
self
|
70
|
-
end if RUBY_VERSION < '1.9'
|
71
|
-
|
72
68
|
# Converts a Date instance to a Time, where the time is set to the beginning of the day.
|
73
69
|
# The timezone can be either :local or :utc (default :local).
|
74
70
|
#
|
75
|
-
# ==== Examples
|
76
71
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
77
72
|
#
|
78
73
|
# date.to_time # => Sat Nov 10 00:00:00 0800 2007
|
@@ -80,27 +75,10 @@ class Date
|
|
80
75
|
#
|
81
76
|
# date.to_time(:utc) # => Sat Nov 10 00:00:00 UTC 2007
|
82
77
|
def to_time(form = :local)
|
83
|
-
::Time.send(
|
78
|
+
::Time.send(form, year, month, day)
|
84
79
|
end
|
85
80
|
|
86
|
-
# Converts a Date instance to a DateTime, where the time is set to the beginning of the day
|
87
|
-
# and UTC offset is set to 0.
|
88
|
-
#
|
89
|
-
# ==== Examples
|
90
|
-
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
91
|
-
#
|
92
|
-
# date.to_datetime # => Sat, 10 Nov 2007 00:00:00 0000
|
93
|
-
def to_datetime
|
94
|
-
::DateTime.civil(year, month, day, 0, 0, 0, 0)
|
95
|
-
end if RUBY_VERSION < '1.9'
|
96
|
-
|
97
|
-
def iso8601
|
98
|
-
strftime('%F')
|
99
|
-
end if RUBY_VERSION < '1.9'
|
100
|
-
|
101
|
-
alias_method :rfc3339, :iso8601 if RUBY_VERSION < '1.9'
|
102
|
-
|
103
81
|
def xmlschema
|
104
|
-
|
82
|
+
in_time_zone.xmlschema
|
105
83
|
end
|
106
84
|
end
|
@@ -2,13 +2,36 @@ require 'date'
|
|
2
2
|
require 'active_support/core_ext/time/zones'
|
3
3
|
|
4
4
|
class Date
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# *DEPRECATED*: Use +Date#in_time_zone+ instead.
|
6
|
+
#
|
7
|
+
# Converts Date to a TimeWithZone in the current zone if <tt>Time.zone</tt> or
|
8
|
+
# <tt>Time.zone_default</tt> is set, otherwise converts Date to a Time via
|
9
|
+
# Date#to_time.
|
7
10
|
def to_time_in_current_zone
|
11
|
+
ActiveSupport::Deprecation.warn 'Date#to_time_in_current_zone is deprecated. Use Date#in_time_zone instead', caller
|
12
|
+
|
8
13
|
if ::Time.zone
|
9
14
|
::Time.zone.local(year, month, day)
|
10
15
|
else
|
11
16
|
to_time
|
12
17
|
end
|
13
18
|
end
|
19
|
+
|
20
|
+
# Converts Date to a TimeWithZone in the current zone if Time.zone or Time.zone_default
|
21
|
+
# is set, otherwise converts Date to a Time via Date#to_time
|
22
|
+
#
|
23
|
+
# Time.zone = 'Hawaii' # => 'Hawaii'
|
24
|
+
# Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
|
25
|
+
#
|
26
|
+
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
|
27
|
+
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
28
|
+
#
|
29
|
+
# Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
|
30
|
+
def in_time_zone(zone = ::Time.zone)
|
31
|
+
if zone
|
32
|
+
::Time.find_zone!(zone).local(year, month, day)
|
33
|
+
else
|
34
|
+
to_time
|
35
|
+
end
|
36
|
+
end
|
14
37
|
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
module DateAndTime
|
2
|
+
module Calculations
|
3
|
+
DAYS_INTO_WEEK = {
|
4
|
+
:monday => 0,
|
5
|
+
:tuesday => 1,
|
6
|
+
:wednesday => 2,
|
7
|
+
:thursday => 3,
|
8
|
+
:friday => 4,
|
9
|
+
:saturday => 5,
|
10
|
+
:sunday => 6
|
11
|
+
}
|
12
|
+
|
13
|
+
# Returns a new date/time representing yesterday.
|
14
|
+
def yesterday
|
15
|
+
advance(:days => -1)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns a new date/time representing tomorrow.
|
19
|
+
def tomorrow
|
20
|
+
advance(:days => 1)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns true if the date/time is today.
|
24
|
+
def today?
|
25
|
+
to_date == ::Date.current
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns true if the date/time is in the past.
|
29
|
+
def past?
|
30
|
+
self < self.class.current
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true if the date/time is in the future.
|
34
|
+
def future?
|
35
|
+
self > self.class.current
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns a new date/time the specified number of days ago.
|
39
|
+
def days_ago(days)
|
40
|
+
advance(:days => -days)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a new date/time the specified number of days in the future.
|
44
|
+
def days_since(days)
|
45
|
+
advance(:days => days)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a new date/time the specified number of weeks ago.
|
49
|
+
def weeks_ago(weeks)
|
50
|
+
advance(:weeks => -weeks)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns a new date/time the specified number of weeks in the future.
|
54
|
+
def weeks_since(weeks)
|
55
|
+
advance(:weeks => weeks)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a new date/time the specified number of months ago.
|
59
|
+
def months_ago(months)
|
60
|
+
advance(:months => -months)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a new date/time the specified number of months in the future.
|
64
|
+
def months_since(months)
|
65
|
+
advance(:months => months)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns a new date/time the specified number of years ago.
|
69
|
+
def years_ago(years)
|
70
|
+
advance(:years => -years)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns a new date/time the specified number of years in the future.
|
74
|
+
def years_since(years)
|
75
|
+
advance(:years => years)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns a new date/time at the start of the month.
|
79
|
+
# DateTime objects will have a time set to 0:00.
|
80
|
+
def beginning_of_month
|
81
|
+
first_hour{ change(:day => 1) }
|
82
|
+
end
|
83
|
+
alias :at_beginning_of_month :beginning_of_month
|
84
|
+
|
85
|
+
# Returns a new date/time at the start of the quarter.
|
86
|
+
# Example: 1st January, 1st July, 1st October.
|
87
|
+
# DateTime objects will have a time set to 0:00.
|
88
|
+
def beginning_of_quarter
|
89
|
+
first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
|
90
|
+
beginning_of_month.change(:month => first_quarter_month)
|
91
|
+
end
|
92
|
+
alias :at_beginning_of_quarter :beginning_of_quarter
|
93
|
+
|
94
|
+
# Returns a new date/time at the end of the quarter.
|
95
|
+
# Example: 31st March, 30th June, 30th September.
|
96
|
+
# DateTIme objects will have a time set to 23:59:59.
|
97
|
+
def end_of_quarter
|
98
|
+
last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
|
99
|
+
beginning_of_month.change(:month => last_quarter_month).end_of_month
|
100
|
+
end
|
101
|
+
alias :at_end_of_quarter :end_of_quarter
|
102
|
+
|
103
|
+
# Return a new date/time at the beginning of the year.
|
104
|
+
# Example: 1st January.
|
105
|
+
# DateTime objects will have a time set to 0:00.
|
106
|
+
def beginning_of_year
|
107
|
+
change(:month => 1).beginning_of_month
|
108
|
+
end
|
109
|
+
alias :at_beginning_of_year :beginning_of_year
|
110
|
+
|
111
|
+
# Returns a new date/time representing the given day in the next week.
|
112
|
+
# Week is assumed to start on +start_day+, default is
|
113
|
+
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
114
|
+
# DateTime objects have their time set to 0:00.
|
115
|
+
def next_week(start_day = Date.beginning_of_week)
|
116
|
+
first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) }
|
117
|
+
end
|
118
|
+
|
119
|
+
# Short-hand for months_since(1).
|
120
|
+
def next_month
|
121
|
+
months_since(1)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Short-hand for months_since(3)
|
125
|
+
def next_quarter
|
126
|
+
months_since(3)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Short-hand for years_since(1).
|
130
|
+
def next_year
|
131
|
+
years_since(1)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns a new date/time representing the given day in the previous week.
|
135
|
+
# Week is assumed to start on +start_day+, default is
|
136
|
+
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
137
|
+
# DateTime objects have their time set to 0:00.
|
138
|
+
def prev_week(start_day = Date.beginning_of_week)
|
139
|
+
first_hour{ weeks_ago(1).beginning_of_week.days_since(days_span(start_day)) }
|
140
|
+
end
|
141
|
+
alias_method :last_week, :prev_week
|
142
|
+
|
143
|
+
# Short-hand for months_ago(1).
|
144
|
+
def prev_month
|
145
|
+
months_ago(1)
|
146
|
+
end
|
147
|
+
alias_method :last_month, :prev_month
|
148
|
+
|
149
|
+
# Short-hand for months_ago(3).
|
150
|
+
def prev_quarter
|
151
|
+
months_ago(3)
|
152
|
+
end
|
153
|
+
alias_method :last_quarter, :prev_quarter
|
154
|
+
|
155
|
+
# Short-hand for years_ago(1).
|
156
|
+
def prev_year
|
157
|
+
years_ago(1)
|
158
|
+
end
|
159
|
+
alias_method :last_year, :prev_year
|
160
|
+
|
161
|
+
# Returns the number of days to the start of the week on the given day.
|
162
|
+
# Week is assumed to start on +start_day+, default is
|
163
|
+
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
164
|
+
def days_to_week_start(start_day = Date.beginning_of_week)
|
165
|
+
start_day_number = DAYS_INTO_WEEK[start_day]
|
166
|
+
current_day_number = wday != 0 ? wday - 1 : 6
|
167
|
+
(current_day_number - start_day_number) % 7
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns a new date/time representing the start of this week on the given day.
|
171
|
+
# Week is assumed to start on +start_day+, default is
|
172
|
+
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
173
|
+
# +DateTime+ objects have their time set to 0:00.
|
174
|
+
def beginning_of_week(start_day = Date.beginning_of_week)
|
175
|
+
result = days_ago(days_to_week_start(start_day))
|
176
|
+
acts_like?(:time) ? result.midnight : result
|
177
|
+
end
|
178
|
+
alias :at_beginning_of_week :beginning_of_week
|
179
|
+
|
180
|
+
# Returns Monday of this week assuming that week starts on Monday.
|
181
|
+
# +DateTime+ objects have their time set to 0:00.
|
182
|
+
def monday
|
183
|
+
beginning_of_week(:monday)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Returns a new date/time representing the end of this week on the given day.
|
187
|
+
# Week is assumed to start on +start_day+, default is
|
188
|
+
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
189
|
+
# DateTime objects have their time set to 23:59:59.
|
190
|
+
def end_of_week(start_day = Date.beginning_of_week)
|
191
|
+
last_hour{ days_since(6 - days_to_week_start(start_day)) }
|
192
|
+
end
|
193
|
+
alias :at_end_of_week :end_of_week
|
194
|
+
|
195
|
+
# Returns Sunday of this week assuming that week starts on Monday.
|
196
|
+
# +DateTime+ objects have their time set to 23:59:59.
|
197
|
+
def sunday
|
198
|
+
end_of_week(:monday)
|
199
|
+
end
|
200
|
+
|
201
|
+
# Returns a new date/time representing the end of the month.
|
202
|
+
# DateTime objects will have a time set to 23:59:59.
|
203
|
+
def end_of_month
|
204
|
+
last_day = ::Time.days_in_month(month, year)
|
205
|
+
last_hour{ days_since(last_day - day) }
|
206
|
+
end
|
207
|
+
alias :at_end_of_month :end_of_month
|
208
|
+
|
209
|
+
# Returns a new date/time representing the end of the year.
|
210
|
+
# DateTime objects will have a time set to 23:59:59.
|
211
|
+
def end_of_year
|
212
|
+
change(:month => 12).end_of_month
|
213
|
+
end
|
214
|
+
alias :at_end_of_year :end_of_year
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def first_hour
|
219
|
+
result = yield
|
220
|
+
acts_like?(:time) ? result.change(:hour => 0) : result
|
221
|
+
end
|
222
|
+
|
223
|
+
def last_hour
|
224
|
+
result = yield
|
225
|
+
acts_like?(:time) ? result.end_of_day : result
|
226
|
+
end
|
227
|
+
|
228
|
+
def days_span(day)
|
229
|
+
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/date_time/acts_like'
|
2
|
+
require 'active_support/core_ext/date_time/calculations'
|
3
|
+
require 'active_support/core_ext/date_time/conversions'
|
4
|
+
require 'active_support/core_ext/date_time/zones'
|
5
|
+
require 'active_support/core_ext/date_time/infinite_comparable'
|
@@ -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,52 @@ 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
|
-
|
139
|
-
# Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
|
140
|
-
def <=>(other)
|
141
|
-
if other.kind_of?(Infinity)
|
142
|
-
super
|
143
|
-
elsif other.respond_to? :to_datetime
|
144
|
-
super other.to_datetime
|
145
|
-
else
|
146
|
-
nil
|
147
|
-
end
|
148
|
-
end
|
149
157
|
end
|