Class: NaturalLangDateParser::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/natural_lang_date_parser.rb

Instance Method Summary collapse

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

Returns:

  • (Boolean)


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_inputObject

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_inputObject

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

Returns:

  • (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

Returns:

  • (Boolean)


121
122
123
# File 'lib/natural_lang_date_parser.rb', line 121

def weekday?(day)
	day && (EXISTING_PATTERNS[:weekdays].split('|').include? day)
end