Sha256: fac669da6161bc9347028fd1a50aee89bf15b9e9dfd1c1a8fb0fde7f50582c08

Contents?: true

Size: 1.33 KB

Versions: 1

Compression:

Stored size: 1.33 KB

Contents

# frozen_string_literal: true

# Parse out time values from a string of text. Uses the provided date as the
# basis for the DateTime generation.
class Parser
  PATTERN = /
    (\A|\s|\() # space or round bracket, to support: "Call Jim (8-9pm)"
    (
      (?<start_time>[1-2]?[0-9]:?[0-9]{2}?)\s?
      (?<start_period>am|pm)?\s?
      (to|-|until)\s?
    )?
    (?<end_time>[1-2]?[0-9]:?[0-9]{2}?)?\s?
    (?<end_period>am|pm)\s?
    (?<time_zone>(
      [ABCDEFGHIJKLMNOPRSTUVWY]
      [A-Z]
      [ACDEGHKLMNORSTUVW]?
      [CDNSTW]?
      [T]?
    ))?\b
  /xi.freeze

  def initialize(text, date: Date.current)
    @text = text
    @date = date
  end

  def call
    match = PATTERN.match(@text)
    result = MatchResult.new(match)
    return nil unless result.valid?

    time_range_from(result)
  end

  private

  def time_range_from(match_result)
    start_time = time_from_string(match_result.start_time_string)
    end_time = time_from_string(match_result.end_time_string)

    if start_time <= end_time
      start_time..end_time
    elsif start_time > end_time
      start_time..(end_time + 1.day)
    end
  rescue ArgumentError
    nil
  end

  def time_from_string(string)
    time_parser.parse(string, @date.to_time)
  end

  # :reek:UtilityFunction so that we can optionally include ActiveSupport
  def time_parser
    ::Time.zone || ::Time
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
time_range_extractor-0.1.2 lib/time_range_extractor/parser.rb