Class: NaturalLangDateParser::Parser
- Inherits:
-
Object
- Object
- NaturalLangDateParser::Parser
- Defined in:
- lib/natural_lang_date_parser.rb
Instance Method Summary collapse
-
#calculate_datetime(type, quantity, tense) ⇒ Object
Defining the DateTime object based on parameters.
-
#date_of_next(day) ⇒ Object
Return the next specific weekeday.
-
#date_of_previous(day) ⇒ Object
Return the previous specific weekeday.
-
#explicit_date?(date) ⇒ Boolean
check if the input refers to an explicit datetime like today etc.
- #find_tense(data) ⇒ Object
-
#format_input ⇒ Object
Formatting the input before parsing.
-
#initialize(datetime) ⇒ Parser
constructor
A new instance of Parser.
-
#interpret_explicit_date(date) ⇒ Object
asiigning values for few explicit dates like tomorrow, yesterday etc.
-
#interpret_relative_date(date) ⇒ Object
Parsing relative date like next friday or next month.
-
#parse_input ⇒ Object
Parsing the Input provided by the user.
- #past_or_future_date(date) ⇒ Object
-
#relative_date?(date) ⇒ Boolean
check whether date is of the form next friday or next month etc & return boolean.
-
#weekday?(day) ⇒ Boolean
returns if its a valid day of the week.
Constructor Details
#initialize(datetime) ⇒ Parser
Returns a new instance of Parser.
17 18 19 20 |
# File 'lib/natural_lang_date_parser.rb', line 17 def initialize(datetime) @current_datetime = DateTime.now @input_params = datetime end |
Instance Method Details
#calculate_datetime(type, quantity, tense) ⇒ Object
Defining the DateTime object based on parameters.
140 141 142 143 144 145 146 147 |
# 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) ⇒ Object
Return the next specific weekeday. Example: next tuesday
126 127 128 129 130 |
# 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) ⇒ Object
Return the previous specific weekeday. Example: previous tuesday
133 134 135 136 137 |
# 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) ⇒ Boolean
check if the input refers to an explicit datetime like today etc
53 54 55 |
# 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) ⇒ Object
112 113 114 115 116 117 118 |
# 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 ⇒ Object
Formatting the input before parsing.
23 24 25 26 |
# 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) ⇒ Object
asiigning values for few explicit dates like tomorrow, yesterday etc.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# 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) ⇒ Object
Parsing relative date like next friday or next month
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# 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 ⇒ Object
Parsing the Input provided by the user.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# 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) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 |
# 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) ⇒ Boolean
check whether date is of the form next friday or next month etc & return boolean
70 71 72 73 |
# 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) ⇒ Boolean
returns if its a valid day of the week
121 122 123 |
# File 'lib/natural_lang_date_parser.rb', line 121 def weekday?(day) day && (EXISTING_PATTERNS[:weekdays].split('|').include? day) end |