Class: FlexDate

Inherits:
Object
  • Object
show all
Extended by:
Mappings
Includes:
Comparable
Defined in:
lib/flex_date.rb

Constant Summary collapse

DATE_FORMATS =

Define some preset date formats.

{
  :short      => "%b %e",
  :medium     => "%e %b %Y",
  :long       => "%B %e, %Y",
  :db         => "%Y-%m-%d",
  :number     => "%Y%m%d",
  :rfc822     => "%e %b %Y"
}

Constants included from Mappings

Mappings::MONTHS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mappings

parse_month

Constructor Details

#initialize(year = nil, month = nil, day = nil) ⇒ FlexDate

Initialize the FlexDate with whichever are available: year, month, and day.



49
50
51
# File 'lib/flex_date.rb', line 49

def initialize(year = nil, month = nil, day = nil)
  @year, @month, @day = year, month, day
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object

Pass unimplemented methods along to a regular Date object if possible.



124
125
126
# File 'lib/flex_date.rb', line 124

def method_missing(name, *args)
  real_date.send(name, *args) if complete?
end

Instance Attribute Details

#dayObject

Returns the value of attribute day.



44
45
46
# File 'lib/flex_date.rb', line 44

def day
  @day
end

#monthObject

Returns the value of attribute month.



44
45
46
# File 'lib/flex_date.rb', line 44

def month
  @month
end

#yearObject

Returns the value of attribute year.



44
45
46
# File 'lib/flex_date.rb', line 44

def year
  @year
end

Class Method Details

.parse(str) ⇒ Object

parse friendly dates expects a format of: month day year, month year, or year can be delimited by spaces, “/” or “-”



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/flex_date.rb', line 16

def self.parse(str)
  one, two, three = str.split(/[\s\-\/]/)
  if(!one.nil? and !two.nil? and !three.nil?)
    m = parse_month(one)
    return self.new(three.to_i, m, two.to_i)
  elsif(!one.nil? and !two.nil?)
    m = parse_month(one)
    return self.new(two.to_i, m, nil)
  elsif(!one.nil?)
    return self.new(one.to_i)
  end
end

Instance Method Details

#<=>(other) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/flex_date.rb', line 30

def <=>(other)
  spaceship = 0 # start assuming equal
  %w(year month day).each do |p|
    a = eval("self.#{p}") || 0
    b = eval("other.#{p}") || 0
    break if (spaceship = a <=> b) != 0
  end
  spaceship
end

#==(other) ⇒ Object



40
41
42
# File 'lib/flex_date.rb', line 40

def ==(other)
  [year,month,day] == [other.year, other.month, other.day]
end

#complete?Boolean

Does this FlexDate specify a year, month, and day?

Returns:

  • (Boolean)


89
90
91
# File 'lib/flex_date.rb', line 89

def complete?
  not (@year and @month and @day).nil?
end

#strftime(format = '%F') ⇒ Object

Same as Date#strftime but gracefully removes missing parts.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/flex_date.rb', line 96

def strftime(format = '%F')
  # If we have a complete date, just let Date handle it.
  return real_date.strftime(format) if complete?
  
  # If we have a partial date, define token dependencies.
  dependencies = {
    :year  => %w(C c D F G g u V v w x Y y),
    :month => %w(B b c D F h m u V v w x),
    :day   => %w(A a c D d e F j u V v w x),
    :time  => %w(H I k L M N P p Q R r S s T X Z)
  }

  # Remove tokens that refer to missing parts.
  format = format.gsub(/%([-_0^#]+)?(\d+)?[EO]?(:{1,3}z|.)/m) do |m|
    s, w, c = $1, $2, $3
    ok = true
    dependencies.each do |attr,tokens|
      missing = instance_variable_get("@#{attr}").nil?
      ok = false if (tokens.include?(c) and missing)
    end
    ok ? m : ''
  end
  phony_date.strftime(format)
end

#to_s(format = :medium) ⇒ Object

String representation of a date. Pass a strftime-format string or a symbol which is a key in the DATE_FORMATS hash.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/flex_date.rb', line 69

def to_s(format = :medium)
  format = DATE_FORMATS[format] if format.is_a?(Symbol)
  s = strftime(format)
  
  # Do some rough cleanup (this isn't very "programmatic").
  replacements = [
    [/^[ ,]+/, ''], # leading whitespace and commas
    [/[ ,]+$/, ''], # trailing whitespace and commas
    [/ +, +/, ' '], # commas and whitespace in middle
  ]
  s.strip!
  replacements.each do |r|
    s.gsub!(r[0], r[1])
  end
  s
end