Date#at_end_of_month

/app/.bundle/gems/gems/activesupport-3.0.0.beta/lib/active_support/core_ext/date/calculations.rb:182
  1 require 'date'
  2 require 'active_support/duration'
  3 require 'active_support/core_ext/time/zones'
  4 require 'active_support/core_ext/object/acts_like'
  5 
  6 class Date
  7   class << self
  8     # Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
  9     def yesterday
 10       ::Date.today.yesterday
 11     end
 12 
 13     # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).
 14     def tomorrow
 15       ::Date.today.tomorrow
 16     end
 17 
 18     # Returns Time.zone.today when config.time_zone is set, otherwise just returns Date.today.
 19     def current
 20       ::Time.zone_default ? ::Time.zone.today : ::Date.today
 21     end
 22   end
 23 
 24   # Tells whether the Date object's date lies in the past
 25   def past?
 26     self < ::Date.current
 27   end
 28 
 29   # Tells whether the Date object's date is today
 30   def today?
 31     self.to_date == ::Date.current # we need the to_date because of DateTime
 32   end
 33 
 34   # Tells whether the Date object's date lies in the future
 35   def future?
 36     self > ::Date.current
 37   end
 38 
 39   # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
 40   # and then subtracts the specified number of seconds
 41   def ago(seconds)
 42     to_time.since(-seconds)
 43   end
 44 
 45   # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
 46   # and then adds the specified number of seconds
 47   def since(seconds)
 48     to_time.since(seconds)
 49   end
 50   alias :in :since
 51 
 52   # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
 53   def beginning_of_day
 54     to_time
 55   end
 56   alias :midnight :beginning_of_day
 57   alias :at_midnight :beginning_of_day
 58   alias :at_beginning_of_day :beginning_of_day
 59 
 60   # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
 61   def end_of_day
 62     to_time.end_of_day
 63   end
 64 
 65   def plus_with_duration(other) #:nodoc:
 66     if ActiveSupport::Duration === other
 67       other.since(self)
 68     else
 69       plus_without_duration(other)
 70     end
 71   end
 72   alias_method :plus_without_duration, :+
 73   alias_method :+, :plus_with_duration
 74 
 75   def minus_with_duration(other) #:nodoc:
 76     if ActiveSupport::Duration === other
 77       plus_with_duration(-other)
 78     else
 79       minus_without_duration(other)
 80     end
 81   end
 82   alias_method :minus_without_duration, :-
 83   alias_method :-, :minus_with_duration
 84 
 85   # Provides precise Date calculations for years, months, and days.  The +options+ parameter takes a hash with
 86   # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
 87   def advance(options)
 88     options = options.dup
 89     d = self
 90     d = d >> options.delete(:years) * 12 if options[:years]
 91     d = d >> options.delete(:months)     if options[:months]
 92     d = d +  options.delete(:weeks) * 7  if options[:weeks]
 93     d = d +  options.delete(:days)       if options[:days]
 94     d
 95   end
 96 
 97   # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
 98   #
 99   # Examples:
100   #
101   #   Date.new(2007, 5, 12).change(:day => 1)                  # => Date.new(2007, 5, 1)
102   #   Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)
103   def change(options)
104     ::Date.new(
105       options[:year]  || self.year,
106       options[:month] || self.month,
107       options[:day]   || self.day
108     )
109   end
110 
111   # Returns a new Date/DateTime representing the time a number of specified months ago
112   def months_ago(months)
113     advance(:months => -months)
114   end
115 
116   # Returns a new Date/DateTime representing the time a number of specified months in the future
117   def months_since(months)
118     advance(:months => months)
119   end
120 
121   # Returns a new Date/DateTime representing the time a number of specified years ago
122   def years_ago(years)
123     advance(:years => -years)
124   end
125 
126   # Returns a new Date/DateTime representing the time a number of specified years in the future
127   def years_since(years)
128     advance(:years => years)
129   end
130 
131   # Short-hand for years_ago(1)
132   def last_year
133     years_ago(1)
134   end
135 
136   # Short-hand for years_since(1)
137   def next_year
138     years_since(1)
139   end unless method_defined?(:next_year)
140 
141   # Short-hand for months_ago(1)
142   def last_month
143     months_ago(1)
144   end
145 
146   # Short-hand for months_since(1)
147   def next_month
148     months_since(1)
149   end unless method_defined?(:next_month)
150 
151   # Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)
152   def beginning_of_week
153     days_to_monday = self.wday!=0 ? self.wday-1 : 6
154     result = self - days_to_monday
155     self.acts_like?(:time) ? result.midnight : result
156   end
157   alias :monday :beginning_of_week
158   alias :at_beginning_of_week :beginning_of_week
159 
160   # Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59)
161   def end_of_week
162     days_to_sunday = self.wday!=0 ? 7-self.wday : 0
163     result = self + days_to_sunday.days
164     self.acts_like?(:time) ? result.end_of_day : result
165   end
166   alias :at_end_of_week :end_of_week
167 
168   # Returns a new Date/DateTime representing the start of the given day in next week (default is Monday).
169   def next_week(day = :monday)
170     days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
171     result = (self + 7).beginning_of_week + days_into_week[day]
172     self.acts_like?(:time) ? result.change(:hour => 0) : result
173   end
174 
175   # Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
176   def beginning_of_month
177     self.acts_like?(:time) ? change(:day => 1,:hour => 0, :min => 0, :sec => 0) : change(:day => 1)
178   end
179   alias :at_beginning_of_month :beginning_of_month
180 
181   # Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00)
182   def end_of_month
183     last_day = ::Time.days_in_month( self.month, self.year )
184     self.acts_like?(:time) ? change(:day => last_day, :hour => 23, :min => 59, :sec => 59) : change(:day => last_day)
185   end
186   alias :at_end_of_month :end_of_month
187 
188   # Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00)
189   def beginning_of_quarter
190     beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
191   end
192   alias :at_beginning_of_quarter :beginning_of_quarter
193 
194   # Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59)
195   def end_of_quarter
196     beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
197   end
198   alias :at_end_of_quarter :end_of_quarter
199 
200   # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
201   def beginning_of_year
202     self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0) : change(:month => 1, :day => 1)
203   end
204   alias :at_beginning_of_year :beginning_of_year
205 
206   # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
207   def end_of_year
208     self.acts_like?(:time) ? change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
209   end
210   alias :at_end_of_year :end_of_year
211 
212   # Convenience method which returns a new Date/DateTime representing the time 1 day ago
213   def yesterday
214     self - 1
215   end
216 
217   # Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time
218   def tomorrow
219     self + 1
220   end
221 end