| Module | ActiveSupport::CoreExtensions::Time::Calculations |
| In: |
vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb
|
Enables the use of time calculations within Time itself
| COMMON_YEAR_DAYS_IN_MONTH | = | [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] |
Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 102
102: def advance(options)
103: unless options[:weeks].nil?
104: options[:weeks], partial_weeks = options[:weeks].divmod(1)
105: options[:days] = (options[:days] || 0) + 7 * partial_weeks
106: end
107:
108: unless options[:days].nil?
109: options[:days], partial_days = options[:days].divmod(1)
110: options[:hours] = (options[:hours] || 0) + 24 * partial_days
111: end
112:
113: d = to_date.advance(options)
114: time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
115: seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
116: seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
117: end
Returns a new Time representing the start of the day (0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 203
203: def beginning_of_day
204: #(self - seconds_since_midnight).change(:usec => 0)
205: change(:hour => 0, :min => 0, :sec => 0, :usec => 0)
206: end
Returns a new Time representing the start of the month (1st of the month, 0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 217
217: def beginning_of_month
218: #self - ((self.mday-1).days + self.seconds_since_midnight)
219: change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
220: end
Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 232
232: def beginning_of_quarter
233: beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
234: end
Returns a new Time representing the "start" of this week (Monday, 0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 182
182: def beginning_of_week
183: days_to_monday = self.wday!=0 ? self.wday-1 : 6
184: (self - days_to_monday.days).midnight
185: end
Returns a new Time representing the start of the year (1st of january, 0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 244
244: def beginning_of_year
245: change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
246: end
Returns a new Time where one or more of the elements have been changed according to the options parameter. The time options (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and minute is passed, then sec and usec is set to 0.
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 85
85: def change(options)
86: ::Time.send(
87: self.utc? ? :utc_time : :local_time,
88: options[:year] || self.year,
89: options[:month] || self.month,
90: options[:day] || self.day,
91: options[:hour] || self.hour,
92: options[:min] || (options[:hour] ? 0 : self.min),
93: options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
94: options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
95: )
96: end
Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances can be chronologically compared with a Time
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 291
291: def compare_with_coercion(other)
292: # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
293: other = other.comparable_time if other.respond_to?(:comparable_time)
294: if other.acts_like?(:date)
295: # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
296: to_datetime.compare_without_coercion(other)
297: else
298: compare_without_coercion(other)
299: end
300: end
Returns a new Time representing the end of the month (end of the last day of the month)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 224
224: def end_of_month
225: #self - ((self.mday-1).days + self.seconds_since_midnight)
226: last_day = ::Time.days_in_month( self.month, self.year )
227: change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
228: end
Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 238
238: def end_of_quarter
239: beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
240: end
Returns a new Time representing the end of this week (Sunday, 23:59:59)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 190
190: def end_of_week
191: days_to_sunday = self.wday!=0 ? 7-self.wday : 0
192: (self + days_to_sunday.days).end_of_day
193: end
Returns a new Time representing the end of the year (end of the 31st of december)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 250
250: def end_of_year
251: change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
252: end
Short-hand for months_ago(1)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 172
172: def last_month
173: months_ago(1)
174: end
Time#- can also be used to determine the number of seconds between two Time instances. We‘re layering on additional behavior so that ActiveSupport::TimeWithZone instances are coerced into values that Time#- will recognize
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 284
284: def minus_with_coercion(other)
285: other = other.comparable_time if other.respond_to?(:comparable_time)
286: minus_without_coercion(other)
287: end
Short-hand for months_since(1)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 177
177: def next_month
178: months_since(1)
179: end
Returns a new Time representing the start of the given day in next week (default is Monday).
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 197
197: def next_week(day = :monday)
198: days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
199: since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
200: end
Short-hand for years_since(1)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 166
166: def next_year
167: years_since(1)
168: end
Seconds since midnight: Time.now.seconds_since_midnight
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 78
78: def seconds_since_midnight
79: self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
80: end
Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around the Numeric extension.
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 126
126: def since(seconds)
127: f = seconds.since(self)
128: if ActiveSupport::Duration === seconds
129: f
130: else
131: initial_dst = self.dst? ? 1 : 0
132: final_dst = f.dst? ? 1 : 0
133: (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
134: end
135: rescue
136: self.to_datetime.since(seconds)
137: end
Tells whether the Time object‘s time is today
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 68
68: def today?
69: self.to_date == ::Date.current
70: end