Module: Useful::RubyExtensionsFromRails::Date

Included in:
Date
Defined in:
lib/useful/ruby_extensions_from_rails/date.rb

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

DATE_FORMATS =
{
  :short        => "%e %b",
  :long         => "%B %e, %Y",
  :db           => "%Y-%m-%d",
  :number       => "%Y%m%d",
  :long_ordinal => lambda { |date| date.strftime("%B #{date.day.ordinalize}, %Y") }, # => "April 25th, 2007"
  :rfc822       => "%e %b %Y"
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 18

def self.included(klass)
  klass.extend(ClassMethods) if klass.kind_of?(Class)
  
  klass.instance_eval do
    alias_method :to_default_s, :to_s
    alias_method :to_s, :to_formatted_s
    alias_method :default_inspect, :inspect
    alias_method :inspect, :readable_inspect

    # Ruby 1.9 has Date#to_time which converts to localtime only.
    remove_method :to_time if klass.instance_methods.include?(:to_time)

    # Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
    remove_method :xmlschema if klass.instance_methods.include?(:xmlschema)
  end
end

Instance Method Details

#acts_like_date?Boolean

Enable more predictable duck-typing on Date-like classes. See Object#acts_like?.

Returns:

  • (Boolean)


56
57
58
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 56

def acts_like_date?
  true
end

#advance(options) ⇒ Object

Provides precise Date calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days.



77
78
79
80
81
82
83
84
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 77

def advance(options)
  d = self
  d = d >> options.delete(:years) * 12 if options[:years]
  d = d >> options.delete(:months)     if options[:months]
  d = d +  options.delete(:weeks) * 7  if options[:weeks]
  d = d +  options.delete(:days)       if options[:days]
  d
end

#beginning_of_dayObject Also known as: midnight, at_midnight, at_beginning_of_day

Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)



101
102
103
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 101

def beginning_of_day
  to_time
end

#beginning_of_monthObject Also known as: at_beginning_of_month

Returns a new Date representing the start of the month (1st of the month)



136
137
138
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 136

def beginning_of_month
  change(:day => 1)
end

#beginning_of_quarterObject Also known as: at_beginning_of_quarter

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)



148
149
150
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 148

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 Date representing the “start” of this week (i.e, Monday; DateTime objects will have time set to 0:00)



115
116
117
118
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 115

def beginning_of_week
  days_to_monday = self.wday!=0 ? self.wday-1 : 6
  self - days_to_monday
end

#beginning_of_yearObject Also known as: at_beginning_of_year

Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)



160
161
162
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 160

def beginning_of_year
  change(:month => 1, :day => 1)
end

#change(options) ⇒ Object

Returns a new Date where one or more of the elements have been changed according to the options parameter.

Examples:

Date.new(2007, 5, 12).change(:day => 1)                  # => Date.new(2007, 5, 1)
Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)


92
93
94
95
96
97
98
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 92

def change(options)
  ::Date.new(
    options[:year]  || self.year,
    options[:month] || self.month,
    options[:day]   || self.day
  )
end

#end_of_dayObject Also known as: at_end_of_day

Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)



109
110
111
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 109

def end_of_day
  to_time.end_of_day
end

#end_of_monthObject Also known as: at_end_of_month

Returns a new Date representing the end of the month (last day of the month)



142
143
144
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 142

def end_of_month
  change(:day => ::Time.days_in_month( self.month, self.year ))
end

#end_of_quarterObject Also known as: at_end_of_quarter

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)



154
155
156
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 154

def end_of_quarter
  beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
end

#end_of_weekObject Also known as: at_end_of_week

Returns a new Date representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59)



123
124
125
126
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 123

def end_of_week
  days_to_sunday = self.wday!=0 ? 7-self.wday : 0
  self + days_to_sunday.days
end

#end_of_yearObject Also known as: at_end_of_year

Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)



166
167
168
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 166

def end_of_year
  change(:month => 12, :day => 31)
end

#future?Boolean

Tells whether the Date object’s date lies in the future

Returns:

  • (Boolean)


71
72
73
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 71

def future?
  self > ::Date.current
end

#next_week(day = :monday) ⇒ Object

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



130
131
132
133
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 130

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

#past?Boolean

Tells whether the Date object’s date lies in the past

Returns:

  • (Boolean)


61
62
63
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 61

def past?
  self < ::Date.current
end

#readable_inspectObject

Overrides the default inspect method with a human readable one, e.g., “Mon, 21 Feb 2005”



217
218
219
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 217

def readable_inspect
  strftime("%a, %d %b %Y")
end

#to_formatted_s(format = :default) ⇒ Object

Convert to a formatted string. See DATE_FORMATS for predefined formats.

This method is aliased to to_s.

Examples

date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007

date.to_formatted_s(:db)            # => "2007-11-10"
date.to_s(:db)                      # => "2007-11-10"

date.to_formatted_s(:short)         # => "10 Nov"
date.to_formatted_s(:long)          # => "November 10, 2007"
date.to_formatted_s(:long_ordinal)  # => "November 10th, 2007"
date.to_formatted_s(:rfc822)        # => "10 Nov 2007"

Adding your own time formats to to_formatted_s

You can add your own formats to the Date::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a date argument as the value.

# config/initializers/time_formats.rb
Date::DATE_FORMATS[:month_and_year] = "%B %Y"
Date::DATE_FORMATS[:short_ordinal] = lambda { |date| date.strftime("%B #{date.day.ordinalize}") }


204
205
206
207
208
209
210
211
212
213
214
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 204

def to_formatted_s(format = :default)
  if formatter = DATE_FORMATS[format]
    if formatter.respond_to?(:call)
      formatter.call(self).to_s
    else
      strftime(formatter)
    end
  else
    to_default_s
  end
end

#to_time(form = :local) ⇒ Object

Converts a Date instance to a Time, where the time is set to the beginning of the day. The timezone can be either :local or :utc (default :local).

Examples

date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007

date.to_time                   # => Sat Nov 10 00:00:00 0800 2007
date.to_time(:local)           # => Sat Nov 10 00:00:00 0800 2007

date.to_time(:utc)             # => Sat Nov 10 00:00:00 UTC 2007


231
232
233
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 231

def to_time(form = :local)
  ::Time.send("#{form}_time", year, month, day)
end

#today?Boolean

Tells whether the Date object’s date is today

Returns:

  • (Boolean)


66
67
68
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 66

def today?
  self.to_date == ::Date.current # we need the to_date because of DateTime
end

#tomorrowObject

Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time



177
178
179
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 177

def tomorrow
  self + 1
end

#xmlschemaObject



235
236
237
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 235

def xmlschema
  to_time.xmlschema
end

#yesterdayObject

Convenience method which returns a new Date/DateTime representing the time 1 day ago



172
173
174
# File 'lib/useful/ruby_extensions_from_rails/date.rb', line 172

def yesterday
  self - 1
end