Froze rails gems
[depot.git] / vendor / rails / activesupport / lib / active_support / core_ext / date_time / calculations.rb
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
11 base.class_eval do
12 alias_method :compare_without_coercion, :<=>
13 alias_method :<=>, :compare_with_coercion
14 end
15 end
16
17 module ClassMethods
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
19 def local_offset
20 ::Time.local(2007).utc_offset.to_r / 86400
21 end
22
23 def current
24 ::Time.zone_default ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
25 end
26 end
27
28 # Tells whether the DateTime object's datetime lies in the past
29 def past?
30 self < ::DateTime.current
31 end
32
33 # Tells whether the DateTime object's datetime lies in the future
34 def future?
35 self > ::DateTime.current
36 end
37
38 # Seconds since midnight: DateTime.now.seconds_since_midnight
39 def seconds_since_midnight
40 self.sec + (self.min * 60) + (self.hour * 3600)
41 end
42
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.
46 def change(options)
47 ::DateTime.civil(
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
56 )
57 end
58
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>.
63 def advance(options)
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)
68 end
69
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!
72 def ago(seconds)
73 self.since(-seconds)
74 end
75
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!
78 def since(seconds)
79 self + Rational(seconds.round, 86400)
80 end
81 alias :in :since
82
83 # Returns a new DateTime representing the start of the day (0:00)
84 def beginning_of_day
85 change(:hour => 0)
86 end
87 alias :midnight :beginning_of_day
88 alias :at_midnight :beginning_of_day
89 alias :at_beginning_of_day :beginning_of_day
90
91 # Returns a new DateTime representing the end of the day (23:59:59)
92 def end_of_day
93 change(:hour => 23, :min => 59, :sec => 59)
94 end
95
96 # Adjusts DateTime to UTC by adding its offset value; offset is set to 0
97 #
98 # Example:
99 #
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
102 def utc
103 new_offset(0)
104 end
105 alias_method :getutc, :utc
106
107 # Returns true if offset == 0
108 def utc?
109 offset == 0
110 end
111
112 # Returns the offset value in seconds
113 def utc_offset
114 (offset * 86400).to_i
115 end
116
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)
122 end
123 end
124 end
125 end
126 end