3 module ActiveSupport
#:nodoc:
4 module CoreExtensions
#:nodoc:
5 module DateTime
#:nodoc:
6 # Enables the use of time calculations within DateTime itself
8 def self.included(base
) #:nodoc:
9 base
.extend ClassMethods
12 alias_method
:compare_without_coercion, :<=>
13 alias_method
:<=>, :compare_with_coercion
18 # 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
20 ::Time.local(2007).utc_offset
.to_r
/ 86400
24 ::Time.zone_default
? ::Time.zone
.now
.to_datetime
: ::Time.now
.to_datetime
28 # Tells whether the DateTime object's datetime lies in the past
30 self < ::DateTime.current
33 # Tells whether the DateTime object's datetime lies in the future
35 self > ::DateTime.current
38 # Seconds since midnight: DateTime.now.seconds_since_midnight
39 def seconds_since_midnight
40 self.sec
+ (self.min
* 60) + (self.hour
* 3600)
43 # Returns a new DateTime where one or more of the elements have been changed according to the +options+ parameter. The time options
44 # (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and
45 # minute is passed, then sec is set to 0.
48 options
[:year] || self.year
,
49 options
[:month] || self.month
,
50 options
[:day] || self.day
,
51 options
[:hour] || self.hour
,
52 options
[:min] || (options
[:hour] ? 0 : self.min
),
53 options
[:sec] || ((options
[:hour] || options
[:min]) ? 0 : self.sec
),
54 options
[:offset] || self.offset
,
55 options
[:start] || self.start
59 # Uses Date to provide precise Time calculations for years, months, and days.
60 # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
61 # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
62 # <tt>:minutes</tt>, <tt>:seconds</tt>.
64 d
= to_date
.advance(options
)
65 datetime_advanced_by_date
= change(:year => d
.year
, :month => d
.month
, :day => d
.day
)
66 seconds_to_advance
= (options
[:seconds] || 0) + (options
[:minutes] || 0) * 60 + (options
[:hours] || 0) * 3600
67 seconds_to_advance
== 0 ? datetime_advanced_by_date
: datetime_advanced_by_date
.since(seconds_to_advance
)
70 # Returns a new DateTime representing the time a number of seconds ago
71 # Do not use this method in combination with x.months, use months_ago instead!
76 # Returns a new DateTime representing the time a number of seconds since the instance time
77 # Do not use this method in combination with x.months, use months_since instead!
79 self + Rational(seconds
.round
, 86400)
83 # Returns a new DateTime representing the start of the day (0:00)
87 alias :midnight :beginning_of_day
88 alias :at_midnight :beginning_of_day
89 alias :at_beginning_of_day :beginning_of_day
91 # Returns a new DateTime representing the end of the day (23:59:59)
93 change(:hour => 23, :min => 59, :sec => 59)
96 # Adjusts DateTime to UTC by adding its offset value; offset is set to 0
100 # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
101 # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
105 alias_method
:getutc, :utc
107 # Returns true if offset == 0
112 # Returns the offset value in seconds
114 (offset
* 86400).to_i
117 # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
118 def compare_with_coercion(other
)
119 other
= other
.comparable_time
if other
.respond_to
?(:comparable_time)
120 other
= other
.to_datetime
unless other
.acts_like
?(:date)
121 compare_without_coercion(other
)