module DateExtensions def rest_of_days_in_week (0...(7 - wday)).map { |i| self + i } end def rest_of_days_in_month (0..(days_in_month - day)).map { |i| self + i } end def rest_of_days_in_year (0..((leap? ? 366 : 365) - yday)).map { |i| self + i } end def start_of_week self - wday end def start_of_next_week(interval = 1) self + (7 * interval) - wday end def start_of_month Date.new(year, month, 1) end def start_of_next_month(interval = 1) new_month, new_year = month + interval, year until new_month <= 12 do new_month -= 12 new_year += 1 end Date.new(new_year, new_month, 1) end def start_of_next_year(interval = 1) Date.new(year + interval, 1, 1) end def occurrence_in_month?(type) case type.to_s when 'first' (1..7).include?(day) when 'second' (8..14).include?(day) when 'third' (15..21).include?(day) when 'fourth' (22..28).include?(day) when 'last' day > days_in_month - 7 end end def weekday? (1..5).include?(wday) end def days_in_month self.class.days_in_month(year, month) end end # Compatibility with Ruby < 1.8.6 unless Date.const_defined?(:Format) module Date::Format Date.constants.each do |constant| const_set(constant, Date.const_get(constant)) end end end class Date NORMAL_MONTH_LENGTHS = { 1 => 31, 2 => 28, 3 => 31, 4 => 30, 5 => 31, 6 => 30, 7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31 } unless const_defined? :NORMAL_MONTH_LENGTHS def self.days_in_month(year, month) days = NORMAL_MONTH_LENGTHS[month] days += 1 if new(year, month, 1).leap? && month == 2 days end include DateExtensions end