class NaturalLangDateParser::Parser
Public Class Methods
new(datetime)
click to toggle source
# File lib/natural_lang_date_parser.rb, line 17 def initialize(datetime) @current_datetime = DateTime.now @input_params = datetime end
Public Instance Methods
calculate_datetime(type, quantity, tense)
click to toggle source
Defining the DateTime object based on parameters.
# File lib/natural_lang_date_parser.rb, line 140 def calculate_datetime(type, quantity, tense) # converting week to days as ruby doesnt have explicit method for week. if type.singularize == 'week' type = 'days' quantity = quantity * 7 end quantity.send(type).send(tense) end
date_of_next(day)
click to toggle source
Return the next specific weekeday. Example: next tuesday
# File lib/natural_lang_date_parser.rb, line 126 def date_of_next(day) day_required = DateTime.parse(day) delta = day_required > DateTime.now ? 0 : 7 (day_required + delta) end
date_of_previous(day)
click to toggle source
Return the previous specific weekeday. Example: previous tuesday
# File lib/natural_lang_date_parser.rb, line 133 def date_of_previous(day) day_required = DateTime.parse(day) delta = day_required < DateTime.now ? 0 : 7 (day_required - delta) end
explicit_date?(date)
click to toggle source
check if the input refers to an explicit datetime like today etc
# File lib/natural_lang_date_parser.rb, line 53 def explicit_date?(date) !(/(?<relative_date>#{EXISTING_PATTERNS[:explicit_dates]})/.match(date)).nil? end
find_tense(data)
click to toggle source
# File lib/natural_lang_date_parser.rb, line 112 def find_tense data if ['ago', 'before'].include? data 'ago' else 'from_now' end end
format_input()
click to toggle source
Formatting the input before parsing.
# File lib/natural_lang_date_parser.rb, line 23 def format_input # removing white spaces at the beginning and the end @input_params = @input_params.downcase.strip() end
interpret_explicit_date(date)
click to toggle source
asiigning values for few explicit dates like tomorrow, yesterday etc.
# File lib/natural_lang_date_parser.rb, line 76 def interpret_explicit_date date case date when 'today' DateTime.now when 'tomorrow' 1.days.from_now when 'yesterday' 1.days.ago when 'day after tomorrow' 2.days.from_now when 'day before yesterday' 2.days.ago else nil end end
interpret_relative_date(date)
click to toggle source
Parsing relative date like next friday or next month
# File lib/natural_lang_date_parser.rb, line 94 def interpret_relative_date date all_durations = EXISTING_PATTERNS[:weekdays] + EXISTING_PATTERNS[:months] + EXISTING_PATTERNS[:durations] relative_date = /(?<tense>#{EXISTING_PATTERNS[:relative_tense]}) (?<type>#{all_durations})(\s at)*/.match(date) # Check if the user is referring to a weekday if weekday?(relative_date[:type]) if (relative_date[:tense] == 'next') date_of_next(relative_date[:type]) else date_of_previous(relative_date[:type]) end else tense = (relative_date[:tense] == 'next') ? 'from_now' : 'ago' calculate_datetime(relative_date[:type], 1, tense) end end
parse_input()
click to toggle source
Parsing the Input provided by the user.
# File lib/natural_lang_date_parser.rb, line 29 def parse_input format_input p "Input is #{@input_params}" #begin # check if the input refers to an explicit datetime like today etc if explicit_date? @input_params interpret_explicit_date @input_params # check if the input refers to relative input like next friday or next month etc elsif relative_date? @input_params interpret_relative_date @input_params # check if the input refers to a past of future date and interpret it elsif date = past_or_future_date(@input_params) date # Try Ruby Date Parser else DateTime.parse(@input_params) end #rescue # p "Sorry!! Something went wrong. Pls. check and try again" #end end
past_or_future_date(date)
click to toggle source
# File lib/natural_lang_date_parser.rb, line 57 def past_or_future_date date # when date is of the form 2 weeks ago if parsed_data = (/(?<quantity>\d+) (?<duration>#{EXISTING_PATTERNS[:durations]}) (?<tense>ago|later|after)*/.match(date)) calculate_datetime(parsed_data[:duration], parsed_data[:quantity].to_i,find_tense(parsed_data[:tense])) # when date is of the form in 3 hours elsif parsed_data = (/(?<tense>after|in|before) (?<quantity>\d+) (?<duration>#{EXISTING_PATTERNS[:durations]})/.match(date)) calculate_datetime(parsed_data[:duration], parsed_data[:quantity].to_i,find_tense(parsed_data[:tense])) else false end end
relative_date?(date)
click to toggle source
check whether date is of the form next friday or next month etc & return boolean
# File lib/natural_lang_date_parser.rb, line 70 def relative_date? date all_durations = EXISTING_PATTERNS[:weekdays] + EXISTING_PATTERNS[:months] + EXISTING_PATTERNS[:durations] !(/(#{EXISTING_PATTERNS[:relative_tense]}) (#{all_durations})/.match(date)).nil? end
weekday?(day)
click to toggle source
returns if its a valid day of the week
# File lib/natural_lang_date_parser.rb, line 121 def weekday?(day) day && (EXISTING_PATTERNS[:weekdays].split('|').include? day) end