activesupport 1.4.4 → 2.0.0
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.
- data/CHANGELOG +263 -7
- data/lib/active_support.rb +9 -4
- data/lib/active_support/basic_object.rb +5 -0
- data/lib/active_support/buffered_logger.rb +107 -0
- data/lib/active_support/clean_logger.rb +94 -5
- data/lib/active_support/core_ext.rb +4 -1
- data/lib/active_support/core_ext/array.rb +8 -2
- data/lib/active_support/core_ext/array/access.rb +28 -0
- data/lib/active_support/core_ext/array/conversions.rb +28 -15
- data/lib/active_support/core_ext/array/extract_options.rb +19 -0
- data/lib/active_support/core_ext/array/grouping.rb +20 -7
- data/lib/active_support/core_ext/array/random_access.rb +12 -0
- data/lib/active_support/core_ext/bigdecimal.rb +1 -2
- data/lib/active_support/core_ext/bigdecimal/{formatting.rb → conversions.rb} +1 -2
- data/lib/active_support/core_ext/blank.rb +2 -8
- data/lib/active_support/core_ext/cgi.rb +2 -2
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +3 -3
- data/lib/active_support/core_ext/class/removal.rb +2 -2
- data/lib/active_support/core_ext/date.rb +5 -1
- data/lib/active_support/core_ext/date/behavior.rb +13 -0
- data/lib/active_support/core_ext/date/calculations.rb +188 -0
- data/lib/active_support/core_ext/date/conversions.rb +69 -13
- data/lib/active_support/core_ext/date_time.rb +10 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +54 -0
- data/lib/active_support/core_ext/duplicable.rb +37 -0
- data/lib/active_support/core_ext/enumerable.rb +1 -0
- data/lib/active_support/core_ext/exception.rb +2 -2
- data/lib/active_support/core_ext/file.rb +21 -0
- data/lib/active_support/core_ext/float.rb +5 -0
- data/lib/active_support/core_ext/float/rounding.rb +24 -0
- data/lib/active_support/core_ext/hash.rb +5 -5
- data/lib/active_support/core_ext/hash/conversions.rb +86 -34
- data/lib/active_support/core_ext/hash/diff.rb +8 -0
- data/lib/active_support/core_ext/hash/except.rb +24 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +15 -2
- data/lib/active_support/core_ext/hash/keys.rb +10 -3
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -2
- data/lib/active_support/core_ext/hash/slice.rb +28 -0
- data/lib/active_support/core_ext/integer.rb +2 -2
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/kernel/debugger.rb +13 -0
- data/lib/active_support/core_ext/module.rb +8 -7
- data/lib/active_support/core_ext/module/aliasing.rb +17 -5
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/module/delegation.rb +21 -0
- data/lib/active_support/core_ext/name_error.rb +2 -2
- data/lib/active_support/core_ext/numeric.rb +2 -2
- data/lib/active_support/core_ext/numeric/time.rb +30 -11
- data/lib/active_support/core_ext/object.rb +3 -2
- data/lib/active_support/core_ext/object/extending.rb +40 -29
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -0
- data/lib/active_support/core_ext/object/misc.rb +29 -4
- data/lib/active_support/core_ext/pathname.rb +1 -1
- data/lib/active_support/core_ext/range.rb +7 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +22 -0
- data/lib/active_support/core_ext/range/conversions.rb +8 -6
- data/lib/active_support/core_ext/range/include_range.rb +22 -0
- data/lib/active_support/core_ext/range/overlaps.rb +12 -0
- data/lib/active_support/core_ext/string.rb +10 -7
- data/lib/active_support/core_ext/string/conversions.rb +5 -1
- data/lib/active_support/core_ext/string/unicode.rb +2 -2
- data/lib/active_support/core_ext/string/xchar.rb +11 -0
- data/lib/active_support/core_ext/symbol.rb +12 -10
- data/lib/active_support/core_ext/test.rb +1 -0
- data/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
- data/lib/active_support/core_ext/time.rb +4 -2
- data/lib/active_support/core_ext/time/behavior.rb +13 -0
- data/lib/active_support/core_ext/time/calculations.rb +87 -54
- data/lib/active_support/core_ext/time/conversions.rb +71 -10
- data/lib/active_support/dependencies.rb +25 -24
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/duration.rb +86 -0
- data/lib/active_support/inflections.rb +2 -1
- data/lib/active_support/inflector.rb +13 -6
- data/lib/active_support/json.rb +22 -39
- data/lib/active_support/json/decoding.rb +60 -0
- data/lib/active_support/json/encoders/date.rb +5 -0
- data/lib/active_support/json/encoders/date_time.rb +5 -0
- data/lib/active_support/json/encoders/enumerable.rb +12 -0
- data/lib/active_support/json/encoders/false_class.rb +5 -0
- data/lib/active_support/json/encoders/hash.rb +50 -0
- data/lib/active_support/json/encoders/nil_class.rb +5 -0
- data/lib/active_support/json/encoders/numeric.rb +5 -0
- data/lib/active_support/json/encoders/object.rb +6 -0
- data/lib/active_support/json/encoders/regexp.rb +5 -0
- data/lib/active_support/json/encoders/string.rb +30 -0
- data/lib/active_support/json/encoders/symbol.rb +5 -0
- data/lib/active_support/json/encoders/time.rb +5 -0
- data/lib/active_support/json/encoders/true_class.rb +5 -0
- data/lib/active_support/json/encoding.rb +38 -0
- data/lib/active_support/json/variable.rb +10 -0
- data/lib/active_support/multibyte.rb +7 -5
- data/lib/active_support/multibyte/chars.rb +6 -0
- data/lib/active_support/multibyte/handlers/utf8_handler.rb +115 -5
- data/lib/active_support/option_merger.rb +7 -7
- data/lib/active_support/ordered_options.rb +22 -17
- data/lib/active_support/test_case.rb +5 -0
- data/lib/active_support/testing.rb +1 -0
- data/lib/active_support/testing/default.rb +12 -0
- data/lib/active_support/values/time_zone.rb +3 -3
- data/lib/active_support/vendor.rb +14 -0
- data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
- data/lib/active_support/vendor/{builder.rb → builder-2.1.2/builder.rb} +0 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xchar.rb +11 -8
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlbase.rb +38 -44
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlevents.rb +1 -1
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlmarkup.rb +40 -39
- data/lib/active_support/vendor/{xml_simple.rb → xml-simple-1.0.11/xmlsimple.rb} +3 -3
- data/lib/active_support/version.rb +3 -3
- data/lib/active_support/whiny_nil.rb +12 -12
- data/lib/activesupport.rb +1 -0
- metadata +69 -17
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -528
- data/lib/active_support/caching_tools.rb +0 -62
- data/lib/active_support/json/encoders.rb +0 -25
- data/lib/active_support/json/encoders/core.rb +0 -70
- data/lib/active_support/reloadable.rb +0 -60
- data/lib/active_support/vendor/builder/blankslate.rb +0 -63
@@ -23,7 +23,7 @@ class Class # :nodoc:
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def class_inheritable_writer(*syms)
|
26
|
-
options = syms.
|
26
|
+
options = syms.extract_options!
|
27
27
|
syms.each do |sym|
|
28
28
|
class_eval <<-EOS
|
29
29
|
def self.#{sym}=(obj)
|
@@ -40,7 +40,7 @@ class Class # :nodoc:
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def class_inheritable_array_writer(*syms)
|
43
|
-
options = syms.
|
43
|
+
options = syms.extract_options!
|
44
44
|
syms.each do |sym|
|
45
45
|
class_eval <<-EOS
|
46
46
|
def self.#{sym}=(obj)
|
@@ -57,7 +57,7 @@ class Class # :nodoc:
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def class_inheritable_hash_writer(*syms)
|
60
|
-
options = syms.
|
60
|
+
options = syms.extract_options!
|
61
61
|
syms.each do |sym|
|
62
62
|
class_eval <<-EOS
|
63
63
|
def self.#{sym}=(obj)
|
@@ -17,8 +17,8 @@ class Class #:nodoc:
|
|
17
17
|
|
18
18
|
# Skip this class if it does not match the current one bound to this name
|
19
19
|
next unless parent.const_defined?(basename) && klass = parent.const_get(basename)
|
20
|
-
|
21
|
-
parent.
|
20
|
+
|
21
|
+
parent.instance_eval { remove_const basename } unless parent == klass
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'date'
|
2
|
-
require
|
2
|
+
require 'active_support/core_ext/date/behavior'
|
3
|
+
require 'active_support/core_ext/date/calculations'
|
4
|
+
require 'active_support/core_ext/date/conversions'
|
3
5
|
|
4
6
|
class Date#:nodoc:
|
7
|
+
include ActiveSupport::CoreExtensions::Date::Behavior
|
8
|
+
include ActiveSupport::CoreExtensions::Date::Calculations
|
5
9
|
include ActiveSupport::CoreExtensions::Date::Conversions
|
6
10
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Date #:nodoc:
|
4
|
+
module Behavior
|
5
|
+
# Enable more predictable duck-typing on Date-like classes. See
|
6
|
+
# Object#acts_like?.
|
7
|
+
def acts_like_date?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Date #:nodoc:
|
4
|
+
# Enables the use of time calculations within Time itself
|
5
|
+
module Calculations
|
6
|
+
def self.included(base) #:nodoc:
|
7
|
+
base.extend ClassMethods
|
8
|
+
|
9
|
+
base.instance_eval do
|
10
|
+
alias_method :plus_without_duration, :+
|
11
|
+
alias_method :+, :plus_with_duration
|
12
|
+
|
13
|
+
alias_method :minus_without_duration, :-
|
14
|
+
alias_method :-, :minus_with_duration
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def yesterday
|
20
|
+
::Date.today.yesterday
|
21
|
+
end
|
22
|
+
|
23
|
+
def tomorrow
|
24
|
+
::Date.today.tomorrow
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
29
|
+
# and then subtracts the specified number of seconds
|
30
|
+
def ago(seconds)
|
31
|
+
to_time.since(-seconds)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
35
|
+
# and then adds the specified number of seconds
|
36
|
+
def since(seconds)
|
37
|
+
to_time.since(seconds)
|
38
|
+
end
|
39
|
+
alias :in :since
|
40
|
+
|
41
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
42
|
+
def beginning_of_day
|
43
|
+
to_time
|
44
|
+
end
|
45
|
+
alias :midnight :beginning_of_day
|
46
|
+
alias :at_midnight :beginning_of_day
|
47
|
+
alias :at_beginning_of_day :beginning_of_day
|
48
|
+
|
49
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
|
50
|
+
def end_of_day
|
51
|
+
to_time.end_of_day
|
52
|
+
end
|
53
|
+
|
54
|
+
def plus_with_duration(other) #:nodoc:
|
55
|
+
if ActiveSupport::Duration === other
|
56
|
+
other.since(self)
|
57
|
+
else
|
58
|
+
plus_without_duration(other)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def minus_with_duration(other) #:nodoc:
|
63
|
+
if ActiveSupport::Duration === other
|
64
|
+
plus_with_duration(-other)
|
65
|
+
else
|
66
|
+
minus_without_duration(other)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
|
71
|
+
# any of these keys: :years, :months, :weeks, :days.
|
72
|
+
def advance(options)
|
73
|
+
d = self
|
74
|
+
d = d >> options.delete(:years) * 12 if options[:years]
|
75
|
+
d = d >> options.delete(:months) if options[:months]
|
76
|
+
d = d + options.delete(:weeks) * 7 if options[:weeks]
|
77
|
+
d = d + options.delete(:days) if options[:days]
|
78
|
+
d
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
|
82
|
+
#
|
83
|
+
# Examples:
|
84
|
+
#
|
85
|
+
# Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 1)
|
86
|
+
# Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)
|
87
|
+
def change(options)
|
88
|
+
::Date.new(
|
89
|
+
options[:year] || self.year,
|
90
|
+
options[:month] || self.month,
|
91
|
+
options[:day] || self.day
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns a new Date/DateTime representing the time a number of specified months ago
|
96
|
+
def months_ago(months)
|
97
|
+
advance(:months => -months)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns a new Date/DateTime representing the time a number of specified months in the future
|
101
|
+
def months_since(months)
|
102
|
+
advance(:months => months)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns a new Date/DateTime representing the time a number of specified years ago
|
106
|
+
def years_ago(years)
|
107
|
+
advance(:years => -years)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns a new Date/DateTime representing the time a number of specified years in the future
|
111
|
+
def years_since(years)
|
112
|
+
advance(:years => years)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Short-hand for years_ago(1)
|
116
|
+
def last_year
|
117
|
+
years_ago(1)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Short-hand for years_since(1)
|
121
|
+
def next_year
|
122
|
+
years_since(1)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Short-hand for months_ago(1)
|
126
|
+
def last_month
|
127
|
+
months_ago(1)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Short-hand for months_since(1)
|
131
|
+
def next_month
|
132
|
+
months_since(1)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)
|
136
|
+
def beginning_of_week
|
137
|
+
days_to_monday = self.wday!=0 ? self.wday-1 : 6
|
138
|
+
result = self - days_to_monday
|
139
|
+
self.acts_like?(:time) ? result.midnight : result
|
140
|
+
end
|
141
|
+
alias :monday :beginning_of_week
|
142
|
+
alias :at_beginning_of_week :beginning_of_week
|
143
|
+
|
144
|
+
# Returns a new Date/DateTime representing the start of the given day in next week (default is Monday).
|
145
|
+
def next_week(day = :monday)
|
146
|
+
days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
|
147
|
+
result = (self + 7).beginning_of_week + days_into_week[day]
|
148
|
+
self.acts_like?(:time) ? result.change(:hour => 0) : result
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
|
152
|
+
def beginning_of_month
|
153
|
+
self.acts_like?(:time) ? change(:day => 1,:hour => 0, :min => 0, :sec => 0) : change(:day => 1)
|
154
|
+
end
|
155
|
+
alias :at_beginning_of_month :beginning_of_month
|
156
|
+
|
157
|
+
# Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00)
|
158
|
+
def end_of_month
|
159
|
+
last_day = ::Time.days_in_month( self.month, self.year )
|
160
|
+
self.acts_like?(:time) ? change(:day => last_day, :hour => 23, :min => 59, :sec => 59) : change(:day => last_day)
|
161
|
+
end
|
162
|
+
alias :at_end_of_month :end_of_month
|
163
|
+
|
164
|
+
# Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00)
|
165
|
+
def beginning_of_quarter
|
166
|
+
beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
|
167
|
+
end
|
168
|
+
alias :at_beginning_of_quarter :beginning_of_quarter
|
169
|
+
|
170
|
+
# Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
|
171
|
+
def beginning_of_year
|
172
|
+
self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0) : change(:month => 1, :day => 1)
|
173
|
+
end
|
174
|
+
alias :at_beginning_of_year :beginning_of_year
|
175
|
+
|
176
|
+
# Convenience method which returns a new Date/DateTime representing the time 1 day ago
|
177
|
+
def yesterday
|
178
|
+
self - 1
|
179
|
+
end
|
180
|
+
|
181
|
+
# Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time
|
182
|
+
def tomorrow
|
183
|
+
self + 1
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -4,32 +4,88 @@ module ActiveSupport #:nodoc:
|
|
4
4
|
# Getting dates in different convenient string representations and other objects
|
5
5
|
module Conversions
|
6
6
|
DATE_FORMATS = {
|
7
|
-
:short
|
8
|
-
:long
|
7
|
+
:short => "%e %b",
|
8
|
+
:long => "%B %e, %Y",
|
9
|
+
:db => "%Y-%m-%d",
|
10
|
+
:long_ordinal => lambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") }, # => "April 25th, 2007"
|
11
|
+
:rfc822 => "%e %b %Y"
|
9
12
|
}
|
10
13
|
|
11
|
-
def self.included(
|
12
|
-
|
13
|
-
|
14
|
+
def self.included(base) #:nodoc:
|
15
|
+
base.instance_eval do
|
16
|
+
alias_method :to_default_s, :to_s
|
17
|
+
alias_method :to_s, :to_formatted_s
|
18
|
+
alias_method :default_inspect, :inspect
|
19
|
+
alias_method :inspect, :readable_inspect
|
20
|
+
|
21
|
+
# Ruby 1.9 has Date#to_time which converts to localtime only.
|
22
|
+
remove_method :to_time if base.instance_methods.include?(:to_time)
|
23
|
+
end
|
14
24
|
end
|
15
25
|
|
26
|
+
# Convert to a formatted string - see DATE_FORMATS for predefined formats.
|
27
|
+
# You can also add your own formats to the DATE_FORMATS constant and use them with this method.
|
28
|
+
#
|
29
|
+
# This method is also aliased as <tt>to_s</tt>.
|
30
|
+
#
|
31
|
+
# ==== Examples:
|
32
|
+
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
33
|
+
#
|
34
|
+
# date.to_formatted_s(:db) # => "2007-11-10"
|
35
|
+
# date.to_s(:db) # => "2007-11-10"
|
36
|
+
#
|
37
|
+
# date.to_formatted_s(:short) # => "10 Nov"
|
38
|
+
# date.to_formatted_s(:long) # => "November 10, 2007"
|
39
|
+
# date.to_formatted_s(:long_ordinal) # => "November 10th, 2007"
|
40
|
+
# date.to_formatted_s(:rfc822) # => "10 Nov 2007"
|
16
41
|
def to_formatted_s(format = :default)
|
17
|
-
|
42
|
+
if formatter = DATE_FORMATS[format]
|
43
|
+
if formatter.respond_to?(:call)
|
44
|
+
formatter.call(self).to_s
|
45
|
+
else
|
46
|
+
strftime(formatter)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
to_default_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
54
|
+
def readable_inspect
|
55
|
+
strftime("%a, %d %b %Y")
|
18
56
|
end
|
19
57
|
|
20
|
-
#
|
58
|
+
# A method to keep Time, Date and DateTime instances interchangeable on conversions.
|
59
|
+
# In this case, it simply returns +self+.
|
21
60
|
def to_date
|
22
61
|
self
|
23
|
-
end
|
62
|
+
end if RUBY_VERSION < '1.9'
|
24
63
|
|
64
|
+
# Converts a Date instance to a Time, where the time is set to the beginning of the day.
|
65
|
+
# The timezone can be either :local or :utc (default :local).
|
66
|
+
#
|
67
|
+
# ==== Examples:
|
68
|
+
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
69
|
+
#
|
70
|
+
# date.to_time # => Sat Nov 10 00:00:00 0800 2007
|
71
|
+
# date.to_time(:local) # => Sat Nov 10 00:00:00 0800 2007
|
72
|
+
#
|
73
|
+
# date.to_time(:utc) # => Sat Nov 10 00:00:00 UTC 2007
|
25
74
|
def to_time(form = :local)
|
26
|
-
|
27
|
-
::Time.send(form, year, month, day, hour, min, sec)
|
28
|
-
else
|
29
|
-
::Time.send(form, year, month, day)
|
30
|
-
end
|
75
|
+
::Time.send("#{form}_time", year, month, day)
|
31
76
|
end
|
32
77
|
|
78
|
+
# Converts a Date instance to a DateTime, where the time is set to the beginning of the day
|
79
|
+
# and UTC offset is set to 0.
|
80
|
+
#
|
81
|
+
# ==== Example:
|
82
|
+
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
83
|
+
#
|
84
|
+
# date.to_datetime # => Sat, 10 Nov 2007 00:00:00 0000
|
85
|
+
def to_datetime
|
86
|
+
::DateTime.civil(year, month, day, 0, 0, 0, 0)
|
87
|
+
end if RUBY_VERSION < '1.9'
|
88
|
+
|
33
89
|
def xmlschema
|
34
90
|
to_time.xmlschema
|
35
91
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'active_support/core_ext/time/behavior'
|
3
|
+
require 'active_support/core_ext/date_time/calculations'
|
4
|
+
require 'active_support/core_ext/date_time/conversions'
|
5
|
+
|
6
|
+
class DateTime
|
7
|
+
include ActiveSupport::CoreExtensions::Time::Behavior
|
8
|
+
include ActiveSupport::CoreExtensions::DateTime::Calculations
|
9
|
+
include ActiveSupport::CoreExtensions::DateTime::Conversions
|
10
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rational'
|
2
|
+
|
3
|
+
module ActiveSupport #:nodoc:
|
4
|
+
module CoreExtensions #:nodoc:
|
5
|
+
module DateTime #:nodoc:
|
6
|
+
# Enables the use of time calculations within DateTime itself
|
7
|
+
module Calculations
|
8
|
+
def self.included(base) #:nodoc:
|
9
|
+
base.extend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone
|
14
|
+
def local_offset
|
15
|
+
::Time.local(2007).utc_offset.to_r / 86400
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Seconds since midnight: DateTime.now.seconds_since_midnight
|
20
|
+
def seconds_since_midnight
|
21
|
+
self.sec + (self.min * 60) + (self.hour * 3600)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a new DateTime where one or more of the elements have been changed according to the +options+ parameter. The time options
|
25
|
+
# (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and
|
26
|
+
# minute is passed, then sec is set to 0.
|
27
|
+
def change(options)
|
28
|
+
::DateTime.civil(
|
29
|
+
options[:year] || self.year,
|
30
|
+
options[:month] || self.month,
|
31
|
+
options[:day] || self.day,
|
32
|
+
options[:hour] || self.hour,
|
33
|
+
options[:min] || (options[:hour] ? 0 : self.min),
|
34
|
+
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
35
|
+
options[:offset] || self.offset,
|
36
|
+
options[:start] || self.start
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with
|
41
|
+
# any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
|
42
|
+
def advance(options)
|
43
|
+
d = to_date.advance(options)
|
44
|
+
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
|
45
|
+
seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
|
46
|
+
seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date.since(seconds_to_advance)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a new DateTime representing the time a number of seconds ago
|
50
|
+
# Do not use this method in combination with x.months, use months_ago instead!
|
51
|
+
def ago(seconds)
|
52
|
+
self.since(-seconds)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a new DateTime representing the time a number of seconds since the instance time
|
56
|
+
# Do not use this method in combination with x.months, use months_since instead!
|
57
|
+
def since(seconds)
|
58
|
+
self + Rational(seconds.round, 86400)
|
59
|
+
end
|
60
|
+
alias :in :since
|
61
|
+
|
62
|
+
# Returns a new DateTime representing the start of the day (0:00)
|
63
|
+
def beginning_of_day
|
64
|
+
change(:hour => 0)
|
65
|
+
end
|
66
|
+
alias :midnight :beginning_of_day
|
67
|
+
alias :at_midnight :beginning_of_day
|
68
|
+
alias :at_beginning_of_day :beginning_of_day
|
69
|
+
|
70
|
+
# Returns a new DateTime representing the end of the day (23:59:59)
|
71
|
+
def end_of_day
|
72
|
+
change(:hour => 23, :min => 59, :sec => 59)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module DateTime #:nodoc:
|
4
|
+
# Getting datetimes in different convenient string representations and other objects
|
5
|
+
module Conversions
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
alias_method :to_datetime_default_s, :to_s
|
9
|
+
alias_method :to_s, :to_formatted_s
|
10
|
+
alias_method :default_inspect, :inspect
|
11
|
+
alias_method :inspect, :readable_inspect
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_formatted_s(format = :default)
|
16
|
+
if formatter = ::Time::DATE_FORMATS[format]
|
17
|
+
if formatter.respond_to?(:call)
|
18
|
+
formatter.call(self).to_s
|
19
|
+
else
|
20
|
+
strftime(formatter)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
to_datetime_default_s
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000"
|
28
|
+
def readable_inspect
|
29
|
+
to_s(:rfc822)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Converts self to a Ruby Date object; time portion is discarded
|
33
|
+
def to_date
|
34
|
+
::Date.new(year, month, day)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
|
38
|
+
# If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time
|
39
|
+
def to_time
|
40
|
+
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec) : self
|
41
|
+
end
|
42
|
+
|
43
|
+
# To be able to keep Times, Dates and DateTimes interchangeable on conversions
|
44
|
+
def to_datetime
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def xmlschema
|
49
|
+
strftime("%Y-%m-%dT%H:%M:%S#{offset == 0 ? 'Z' : '%Z'}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|