Module: ActiveSupport::CoreExtensions::Time::Calculations

Included in:
Time
Defined in:
lib/active_support/core_ext/time/calculations.rb

Overview

Enables the use of time calculations within Time itself

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

:nodoc:



6
7
8
# File 'lib/active_support/core_ext/time/calculations.rb', line 6

def self.included(base) #:nodoc:
  base.extend(ClassMethods)
end

Instance Method Details

#advance(options) ⇒ Object

Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :months, :days, :years.



49
50
51
52
53
54
# File 'lib/active_support/core_ext/time/calculations.rb', line 49

def advance(options)
  d = ::Date.new(year + (options.delete(:years) || 0), month, day)
  d = d >> options.delete(:months) if options[:months]
  d = d +  options.delete(:days)   if options[:days]
  change(options.merge(:year => d.year, :month => d.month, :mday => d.day))
end

#ago(seconds) ⇒ Object

Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension Do not use this method in combination with x.months, use months_ago instead!



58
59
60
# File 'lib/active_support/core_ext/time/calculations.rb', line 58

def ago(seconds)
  self.since(-seconds)
end

#beginning_of_dayObject Also known as: midnight, at_midnight, at_beginning_of_day

Returns a new Time representing the start of the day (0:00)



145
146
147
# File 'lib/active_support/core_ext/time/calculations.rb', line 145

def beginning_of_day
  (self - self.seconds_since_midnight).change(:usec => 0)
end

#beginning_of_monthObject Also known as: at_beginning_of_month

Returns a new Time representing the start of the month (1st of the month, 0:00)



153
154
155
156
# File 'lib/active_support/core_ext/time/calculations.rb', line 153

def beginning_of_month
  #self - ((self.mday-1).days + self.seconds_since_midnight)
  change(:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
end

#beginning_of_quarterObject Also known as: at_beginning_of_quarter

Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)



168
169
170
# File 'lib/active_support/core_ext/time/calculations.rb', line 168

def beginning_of_quarter
  beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
end

#beginning_of_weekObject Also known as: monday, at_beginning_of_week

Returns a new Time representing the “start” of this week (Monday, 0:00)



131
132
133
134
# File 'lib/active_support/core_ext/time/calculations.rb', line 131

def beginning_of_week
  days_to_monday = self.wday!=0 ? self.wday-1 : 6
  (self - days_to_monday.days).midnight
end

#beginning_of_yearObject Also known as: at_beginning_of_year

Returns a new Time representing the start of the year (1st of january, 0:00)



174
175
176
# File 'lib/active_support/core_ext/time/calculations.rb', line 174

def beginning_of_year
  change(:month => 1,:mday => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
end

#change(options) ⇒ Object

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.



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/active_support/core_ext/time/calculations.rb', line 34

def change(options)
  ::Time.send(
    self.utc? ? :utc : :local, 
    options[:year]  || self.year, 
    options[:month] || self.month, 
    options[:mday]  || self.mday, 
    options[:hour]  || self.hour, 
    options[:min]   || (options[:hour] ? 0 : self.min),
    options[:sec]   || ((options[:hour] || options[:min]) ? 0 : self.sec),
    options[:usec]  || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
  )
end

#end_of_monthObject Also known as: at_end_of_month

Returns a new Time representing the end of the month (last day of the month, 0:00)



160
161
162
163
164
# File 'lib/active_support/core_ext/time/calculations.rb', line 160

def end_of_month
  #self - ((self.mday-1).days + self.seconds_since_midnight)
  last_day = ::Time.days_in_month( self.month, self.year )
  change(:mday => last_day,:hour => 0, :min => 0, :sec => 0, :usec => 0)
end

#last_monthObject

Short-hand for months_ago(1)



121
122
123
# File 'lib/active_support/core_ext/time/calculations.rb', line 121

def last_month
  months_ago(1)
end

#last_yearObject

Short-hand for years_ago(1)



110
111
112
# File 'lib/active_support/core_ext/time/calculations.rb', line 110

def last_year
  years_ago(1)
end

#months_ago(months) ⇒ Object

Returns a new Time representing the time a number of specified months ago



73
74
75
# File 'lib/active_support/core_ext/time/calculations.rb', line 73

def months_ago(months)
  months_since(-months)
end

#months_since(months) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/active_support/core_ext/time/calculations.rb', line 77

def months_since(months)
  year, month, mday = self.year, self.month, self.mday

  month += months

  # in case months is negative
  while month < 1
    month += 12
    year -= 1
  end

  # in case months is positive
  while month > 12
    month -= 12
    year += 1
  end

  max = ::Time.days_in_month(month, year)
  mday = max if mday > max

  change(:year => year, :month => month, :mday => mday)
end

#next_monthObject

Short-hand for months_since(1)



126
127
128
# File 'lib/active_support/core_ext/time/calculations.rb', line 126

def next_month
  months_since(1)
end

#next_week(day = :monday) ⇒ Object

Returns a new Time representing the start of the given day in next week (default is Monday).



139
140
141
142
# File 'lib/active_support/core_ext/time/calculations.rb', line 139

def next_week(day = :monday)
  days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
  since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
end

#next_yearObject

Short-hand for years_since(1)



115
116
117
# File 'lib/active_support/core_ext/time/calculations.rb', line 115

def next_year
  years_since(1)
end

#seconds_since_midnightObject

Seconds since midnight: Time.now.seconds_since_midnight



27
28
29
# File 'lib/active_support/core_ext/time/calculations.rb', line 27

def seconds_since_midnight
  self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
end

#since(seconds) ⇒ Object Also known as: in

Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around the Numeric extension. Do not use this method in combination with x.months, use months_since instead!



64
65
66
67
68
69
# File 'lib/active_support/core_ext/time/calculations.rb', line 64

def since(seconds)
  initial_dst = self.dst? ? 1 : 0
  f = seconds.since(self)
  final_dst   = f.dst? ? 1 : 0
  (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
end

#tomorrowObject

Convenience method which returns a new Time representing the time 1 day since the instance time



185
186
187
# File 'lib/active_support/core_ext/time/calculations.rb', line 185

def tomorrow
  self.since(1.day)
end

#years_ago(years) ⇒ Object

Returns a new Time representing the time a number of specified years ago



101
102
103
# File 'lib/active_support/core_ext/time/calculations.rb', line 101

def years_ago(years)
  change(:year => self.year - years)
end

#years_since(years) ⇒ Object



105
106
107
# File 'lib/active_support/core_ext/time/calculations.rb', line 105

def years_since(years)
  change(:year => self.year + years)
end

#yesterdayObject

Convenience method which returns a new Time representing the time 1 day ago



180
181
182
# File 'lib/active_support/core_ext/time/calculations.rb', line 180

def yesterday
  self.ago(1.day)
end