Class: FuzzyDate

Inherits:
Object
  • Object
show all
Defined in:
lib/fuzzy-date.rb,
lib/fuzzy-date/variables.rb,
lib/fuzzy-date/fuzzy-date.rb

Constant Summary collapse

VERSION =
'0.1.5'
DATE_SEPARATOR =
'[^A-Za-z0-9]'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(date, euro = false) ⇒ FuzzyDate

Returns a new instance of FuzzyDate.



4
5
6
7
# File 'lib/fuzzy-date/fuzzy-date.rb', line 4

def initialize( date, euro = false )
  setup
  analyze date, euro
end

Class Method Details

.parse(date, euro = false) ⇒ Object

Note: This is only for single dates - not ranges.

Possible incoming date formats:

  • YYYY-MM-DD - starts with 3 or 4 digit year, and month and day may be 1 or 2 digits

  • YYYY-MM - 3 or 4 digit year, then 1 or 2 digit month

  • YYYY - 3 or 4 digit year

  • MM-DD-YYYY - 1 or 2 digit month, then 1 or 2 digit day, then 1 to 4 digit year

  • DD-MM-YYYY - 1 or 2 digit day, then 1 or 2 digit month, then 1 to 4 digit year if euro is true

  • MM-YYYY - 1 or 2 digit month, then 1 to 4 digit year

  • DD-MMM - 1 or 2 digit day, then month name or abbreviation

  • DD-MMM-YYYY - 1 or 2 digit day, then month name or abbreviation, then 1 to 4 digit year

  • MMM-YYYY - month name or abbreviation, then 1 to 4 digit year

  • MMM-DD-YYYY - month name or abbreviation, then 1 or 2 digit day, then 1 to 4 digit year

Notes:

  • Commas are optional.

  • Delimiters can be most anything non-alphanumeric.

  • All dates may be suffixed with the era (AD, BC, CE, BCE). AD is assumed.

  • Dates may be prefixed by circa words (Circa, About, Abt).



28
29
30
31
# File 'lib/fuzzy-date.rb', line 28

def self.parse( date, euro = false )
  fuzzy_date = FuzzyDate.new date, euro
  fuzzy_date.to_hash
end

Instance Method Details

#analyze(date, euro) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/fuzzy-date/fuzzy-date.rb', line 9

def analyze( date, euro )

  date = clean_parameter date

  @date_parts[ :original ] = date

  date = massage date
  @date_parts[ :fixed ] = date

  #- Takes care of YYYY
  if date =~ /^(\d{1,4})$/
    year = $1.to_i.to_s
    month = nil
    day = nil

  #- Takes care of YYYY-MM-DD and YYYY-MM
  elsif date =~ /^(\d{3,4})(?:-(\d{1,2})(?:-(\d{1,2}))?)?$/
    year = $1.to_i.to_s
    month = $2 ? $2.to_i.to_s : nil
    day = $3 ? $3.to_i.to_s : nil

  #- Takes care of DD-MM-YYYY
  elsif date =~ /^(\d{1,2})-(\d{1,2})-(\d{1,4})$/ and euro
    day = $1.to_i.to_s
    month = $2.to_i.to_s
    year = $3.to_i.to_s

  #- Takes care of MM-DD-YYYY
  elsif date =~ /^(\d{1,2})-(\d{1,2})-(\d{1,4})$/
    month = $1.to_i.to_s
    day = $2.to_i.to_s
    year = $3.to_i.to_s

  #- Takes care of MM-YYYY
  elsif date =~ /^(\d{1,2})-(\d{1,4})?$/
    month = $1.to_i.to_s
    day = nil
    year = $2.to_i.to_s

  #- Takes care of DD-MMM-YYYY and DD-MMM
  elsif date =~ /^(\d{1,2})(?:-(#{ @month_abbreviations.keys.join( '|' ) }).*?(?:-(\d{1,4}))?)?$/i
    month_text = $2.to_s.capitalize
    month = @month_names.key( @month_abbreviations[ month_text ] ).to_i.to_s
    day = $1.to_i.to_s
    year = $3 ? $3.to_i.to_s : nil

  #- Takes care of MMM-DD-YYYY
  elsif date =~ /^(#{ @month_abbreviations.keys.join( '|' ) }).*?-(\d{1,2})-(\d{1,4})$/i
    month_text = $1.to_s.capitalize
    month = @month_names.key( @month_abbreviations[ month_text ] ).to_i.to_s
    day = $2.to_i.to_s
    year = $3 ? $3.to_i.to_s : nil

  #- Takes care of MMM-YYYY and MMM
  elsif date =~ /^(#{ @month_abbreviations.keys.join( '|' ) }).*?(?:-(\d{1,4}))?$/i
    month_text = $1.to_s.capitalize
    month = @month_names.key( @month_abbreviations[ month_text ] ).to_i.to_s
    day = nil
    year = $2 ? $2.to_i.to_s : nil

  else
    raise ArgumentError.new( 'Cannot parse date.' )
  end

  @date_parts[ :year   ] = year  ? year.to_i   : nil
  @date_parts[ :month  ] = month ? month.to_i  : nil
  @date_parts[ :day    ] = day   ? day.to_i    : nil
  #return { :circa => "day: #{ day }, month: #{ month }, year: #{ year }" }

  #- Some error checking at this point
  if month.to_i > 13
    raise ArgumentError.new( 'Month cannot be greater than 12.' )
  elsif month and day and day.to_i > @days_in_month[ month.to_i ]
    unless month.to_i == 2 and year and Date.parse( '1/1/' + year ).leap? and day.to_i == 29
      raise ArgumentError.new( 'Too many days in this month.' )
    end
  elsif month and month.to_i < 1
    raise ArgumentError.new( 'Month cannot be less than 1.' )
  elsif day and day.to_i < 1
    raise ArgumentError.new( 'Day cannot be less than 1.' )
  end

  month_name = @month_names[ month.to_i ]
  @date_parts[ :month_name ] = month_name

  # ----------------------------------------------------------------------

  show_era = ' ' + @date_parts[ :era ]
  show_circa = @date_parts[ :circa ] == true ? 'About ' : ''

  if year and month and day
    @date_parts[ :short  ] = show_circa + month + '/' + day + '/' + year + show_era
    @date_parts[ :long   ] = show_circa + month_name + ' ' + day + ', ' + year + show_era
    modified_long = show_circa + month_name + ' ' + day + ', ' + year.rjust( 4, "0" ) + show_era
    @date_parts[ :full   ] = show_circa + Date.parse( modified_long ).strftime( '%A,' ) + Date.parse( day + ' ' + month_name + ' ' + year.rjust( 4, "0" ) ).strftime( ' %B %-1d, %Y' ) + show_era
  elsif year and month
    @date_parts[ :short  ] = show_circa + month + '/' + year + show_era
    @date_parts[ :long   ] = show_circa + month_name + ', ' + year + show_era
    @date_parts[ :full   ] = @date_parts[ :long ]
  elsif month and day
    month_text = @month_abbreviations.key(month_text) || month_text
    @date_parts[ :short  ] = show_circa + day + '-' + month_text
    @date_parts[ :long   ] = show_circa + day + ' ' + month_name
    @date_parts[ :full   ] = @date_parts[ :long ]
  elsif year
    @date_parts[ :short  ] = show_circa + year + show_era
    @date_parts[ :long   ] = @date_parts[ :short  ]
    @date_parts[ :full   ] = @date_parts[ :long   ]
  end

  @date_parts

end

#to_hashObject



123
124
125
# File 'lib/fuzzy-date/fuzzy-date.rb', line 123

def to_hash
  @date_parts
end