Sha256: 3d299c8623333bdf2d9c8722fb93de383c9f221d30aecaf5b19ed5accec954a9

Contents?: true

Size: 1.36 KB

Versions: 1

Compression:

Stored size: 1.36 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>(2[0-4]|1[0-9]|[1-9]):?([0-5][0-9])?)\s?
      (?<start_period>am|pm)?\s?
      (to|-|until)\s?
    )?
    (?<end_time>(2[0-4]|1[0-9]|[1-9]):?([0-5][0-9])?)?\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.3 lib/time_range_extractor/parser.rb