Rails Date Parser 1
I became frustrated with date parsing in Rails and Ruby and so created a user friendly parser for dates. I wanted to avoid a big javascript library or using a date-picker widget. Quite frankly, when I am entering dates, I don't like to have to reach for the mouse and scroll through the dates.
So this is a simple to install simple to use extension to the ruby Date class. To use it simply copy the following code to a file named dateparse.rb and place it in the lib directory in your rails app. Then open up the application controller and and put require 'dateparse' at the top of the file. (Note: put it before the class declaration).
Then in your controller or view code use Date.parse_date() in place of Date.parse(). It recognizes the following formats
So this is a simple to install simple to use extension to the ruby Date class. To use it simply copy the following code to a file named dateparse.rb and place it in the lib directory in your rails app. Then open up the application controller and and put require 'dateparse' at the top of the file. (Note: put it before the class declaration).
Then in your controller or view code use Date.parse_date() in place of Date.parse(). It recognizes the following formats
YYYY-mm-dd ISO Standard
mm-dd-YYYY American
mm-dd Assume current year
mm/dd/YYYY American standard
mm/dd
mm.dd.yyyy European
dd.mm.yyyy
dd mmmmm yyyy example: 22 may 1945 or 22nd may 1945
dd mmmmm example: 22 may (current year)
mmmm dd yyyy example: may 22 1945 or may 22nd 1945
mmmm dd, yyyy example: may 22, 1945
mmmm dd example may 22 or may 22nd
dd example 4 or 4th
today (tod) or now common names for days and abbreviations
tomorrow (tom)
yesterday (yes)
Next Week, Last Week, Next Month, Last Month, Next Year, Last Year
+n[units] or -n[units]: Date from today: examples: '+22', '+22 days',
'+22d', '-4 weeks', '-4w', '-4week', '+6 months', '+6m', '+6month',
'-2 years', '-2y'
# This library adds the parse_date method to the Standard Ruby Date Class. # Its purpose is to make the entry of user friendly date formates painless # in Rails applications. # # My motivation for making this was the desire for user friendly date input # in rails applications without resorting to javascript or some kind of widget. # # To use: drop this file into ./lib, require it into the application # controller. # # Written by Tom WillettHope this helps someone.# Version 1.0 # # with a tip of the hat to # Stuart Rackham # and Datetime ToolBocks # # Date Formats recognized by this method: # YYYY-mm-dd ISO Standard # mm-dd-YYYY American # mm-dd Assume current year # mm/dd/YYYY American standard # mm/dd # mm.dd.yyyy European # dd.mm.yyyy # dd mmmmm yyyy example: 22 may 1945 or 22nd may 1945 # dd mmmmm example: 22 may (current year) # mmmm dd yyyy example: may 22 1945 or may 22nd 1945 # mmmm dd, yyyy example: may 22, 1945 # mmmm dd example may 22 or may 22nd # dd example 4 or 4th # today (tod) or now common names for days and abbreviations # tomorrow (tom) # yesterday (yes) # Next Week, Last Week, Next Month, Last Month, Next Year, Last Year # +n[units] or -n[units]: Date from today: examples: '+22', '+22 days', # '+22d', '-4 weeks', '-4w', '-4week', '+6 months', '+6m', '+6month', # '-2 years', '-2y' # class Date # Parse date string with one of the following formats: # # The string argument is first converted to a string with #to_s. # Returns nil if passed nil or an empty string. # Raises ArgumentError if string can't be parsed. # def self.parse_date(org_string) string = org_string.to_s.strip.downcase return nil if org_string.empty? today = Date.today if string =~ /^(\d{4})-(\d{1,2})-(\d{1,2})$/ # YYYY-mm-dd format. ISO Standard year = $1.to_i month = $2.to_i day = $3.to_i elsif string =~ /^(\d{1,2})-(\d{1,2})-(\d{4})$/ # mm-dd-yyyy format year = $3.to_i month = $1.to_i day = $2.to_i elsif string =~ /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/ # mm.dd.yyyy or dd.mm.yyyy format year = $3.to_i if $1.to_i > 12 day = $1.to_i month = $2.to_i else day = $2.to_i month = $1.to_i end elsif string =~ /^(\d{1,2})-(\d{1,2})$/ # mm-dd format year = today.year.to_i month = $1.to_i day = $2.to_i elsif string =~ /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/ # mm/dd/yyyy format year = $3.to_i month = $1.to_i day = $2.to_i elsif string =~ /^(\d{1,2})\/(\d{1,2})$/ # mm/dd format year = today.year month = $1.to_i day = $2.to_i elsif string =~ /^(\d{1,2})(?:st|nd|rd|th)?,? (\w+) (\d{2,4})$/ # 'd mmmm yyyy' format date_array = ParseDate.parsedate("#{$1} #{$2} #{$3}", true) year = date_array[0].to_i month = date_array[1].to_i day = date_array[2].to_i elsif string =~ /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,? (\d{2,4})$/ # 'mmmm d yyyy' format date_array = ParseDate.parsedate("#{$2} #{$1} #{$3}", true) year = date_array[0].to_i month = date_array[1].to_i day = date_array[2].to_i elsif string =~ /^(\d{1,2})(?:st|nd|rd|th)?,? (\w+)$/ # 'd mmmm' format y = today.year.to_s date_array = ParseDate.parsedate("#{$1} #{$2} #{y}", true) year = date_array[0].to_i month = date_array[1].to_i day = date_array[2].to_i elsif string =~ /^(\w+) (\d{1,2})(?:st|nd|rd|th)?,?$/ # 'mmmm d' format y = today.year.to_s date_array = ParseDate.parsedate("#{$2} #{$1} #{y}", true) year = date_array[0].to_i month = date_array[1].to_i day = date_array[2].to_i elsif string =~ /^(\d{1,2})(st|nd|rd|th)?$/ # 'd' format year = today.year month = today.month day = $1.to_i elsif string =~ /^tod[\w]+$|^now$/ # today or now year = today.year month = today.month day = today.day elsif string =~ /^tom/ # tomorrow today += 1 year = today.year month = today.month day = today.day elsif string =~ /^yes/ # yesterday today -= 1 year = today.year month = today.month day = today.day elsif string =~ /^(next|last)\s(week|month|year)$/ # Next Week, Last Week, Next Month, Last Month, Next Year, Last Year year = today.year month = today.month day = today.day case $2 when 'week' if $1 == 'next' today += 7 else today -= 7 end year = today.year month = today.month day = today.day when 'month' month = (($1 == 'next') ? (month + 1) : (month - 1)) if month > 12 month = 1 year += 1 elsif month < 1 month = 12 year -= 1 end when 'year' year = (($1 == 'next') ? (year + 1) : (year - 1)) end elsif string =~ /^([+-]\d+)(?:\s*(d|days?|w|weeks?|m|months?|y|years?))?$/ # Date intervals. year = today.year month = today.month day = today.day n = $1.to_i units = $2 || 'days' case units.first when 'd' today = today + n year = today.year month = today.month day = today.day when 'w' today = today + n*7 year = today.year month = today.month day = today.day when 'm' sign = n <=> 0 month = today.month + sign * (n.abs % 12) year = today.year + sign * (n.abs / 12) if month <1 month += 12 year -= 1 elsif month > 12 month -= 12 year += 1 end when 'y' year = year + n end else raise ArgumentError.new("\"#{org_string}\" is not recognized as a Date") end begin result = Date.new(year,month,day) rescue raise ArgumentError.new("\"#{org_string}\" is not recognized as a Date") end result end end

Awesome! Thanks for taking your time to write and share it!