Method: Doing::ChronifyString#chronify

Defined in:
lib/doing/chronify/string.rb

#chronify(**options) ⇒ DateTime

Converts input string into a Time object when input takes on the following formats: - interval format e.g. '1d2h30m', '45m' etc. - a semantic phrase e.g. 'yesterday 5:30pm' - a strftime e.g. '2016-03-15 15:32:04 PDT'

Parameters:

  • options

    Additional options

Options Hash (**options):

  • :future (Boolean)

    assume future date (default: false)

  • :guess (Symbol)

    :begin or :end to assume beginning or end of arbitrary time range

Returns:

  • (DateTime)

    result

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/doing/chronify/string.rb', line 27

def chronify(**options)
  now = Time.now
  raise Errors::InvalidTimeExpression, "Invalid time expression #{inspect}" if to_s.strip == ''

  secs_ago = if match(/^(\d+)$/)
               # plain number, assume minutes
               Regexp.last_match(1).to_i * 60
             elsif (m = match(/^(?:(?<day>\d+)d)? *(?:(?<hour>\d+)h)? *(?:(?<min>\d+)m)?$/i))
               # day/hour/minute format e.g. 1d2h30m
               [[m['day'], 24 * 3600],
                [m['hour'], 3600],
                [m['min'], 60]].map { |qty, secs| qty ? (qty.to_i * secs) : 0 }.reduce(0, :+)
             end

  if secs_ago
    res = now - secs_ago
    Doing.logger.debug('Parser:', %(date/time string "#{self}" interpreted as #{res} (#{secs_ago} seconds ago)))
  else
    date_string = dup
    date_string = 'today' if date_string.match(Types::REGEX_DAY) && now.strftime('%a') =~ /^#{Regexp.last_match(1)}/i
    date_string = "#{options[:context].to_s} #{date_string}" if date_string =~ Types::REGEX_TIME && options[:context]

    res = Chronic.parse(date_string, {
                          guess: options.fetch(:guess, :begin),
                          context: options.fetch(:future, false) ? :future : :past,
                          ambiguous_time_range: 8
                        })

    Doing.logger.debug('Parser:', %(date/time string "#{self}" interpreted as #{res}))
  end

  res
end