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 - self.seconds_since_midnight).change(:usec => 0) 205: 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 216 216: def beginning_of_month 217: #self - ((self.mday-1).days + self.seconds_since_midnight) 218: change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0) 219: 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 231 231: def beginning_of_quarter 232: beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month }) 233: 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 243 243: def beginning_of_year 244: change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0) 245: 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 290 290: def compare_with_coercion(other) 291: # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison 292: other = other.comparable_time if other.respond_to?(:comparable_time) 293: if other.acts_like?(:date) 294: # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=> 295: to_datetime.compare_without_coercion(other) 296: else 297: compare_without_coercion(other) 298: end 299: end
Returns a new Time representing the end of the day (23:59:59)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 211 211: def end_of_day 212: change(:hour => 23, :min => 59, :sec => 59) 213: end
Returns a new Time representing the end of the month (last day of the month, 0:00)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 223 223: def end_of_month 224: #self - ((self.mday-1).days + self.seconds_since_midnight) 225: last_day = ::Time.days_in_month( self.month, self.year ) 226: change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 0) 227: end
Returns a new Time representing the end of the quarter (last day of march, june, september, december, 23:59:59)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 237 237: def end_of_quarter 238: beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month 239: 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 (31st of december, 23:59:59)
# File vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb, line 249 249: def end_of_year 250: change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59) 251: 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 283 283: def minus_with_coercion(other) 284: other = other.comparable_time if other.respond_to?(:comparable_time) 285: minus_without_coercion(other) 286: 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