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