Module: TranzitoUtils::TimeParser

Defined in:
lib/tranzito_utils/services/time_parser.rb

Class Method Summary collapse

Class Method Details

.parse(time_str = nil, timezone_str = nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/tranzito_utils/services/time_parser.rb', line 5

def self.parse(time_str = nil, timezone_str = nil)
  return nil unless time_str.present?
  return time_str if time_str.is_a?(Time)

  if time_str.is_a?(Integer) || time_str.is_a?(Float) || time_str.to_s.strip.match(/^\d+\z/) # it's only numbers
    return parse("#{time_str}-01-01") if time_str.to_s.length == 4 # Looks a year, valid 8601 format
    # otherwise it's a timestamp
    Time.at(time_str.to_i)
  else
    Time.zone = parse_timezone(timezone_str)
    time = Time.zone.parse(time_str.to_s)
    Time.zone = TranzitoUtils::DEFAULT[:time_zone]
    time
  end
rescue ArgumentError => e
  # Try to parse some other, unexpected formats -
  paychex_formatted = %r{(?<month>\d+)/(?<day>\d+)/(?<year>\d+) (?<hour>\d\d):(?<minute>\d\d) (?<ampm>\w\w)}.match(time_str)
  ie11_formatted = %r{(?<month>\d+)/(?<day>\d+)/(?<year>\d+)}.match(time_str)
  just_date = %r{(?<year>\d{4})[^\d|\w](?<month>\d\d?)}.match(time_str)
  just_date_backward = %r{(?<month>\d\d?)[^\d|\w](?<year>\d{4})}.match(time_str)

  # Get the successful matching regex group, and then reformat it in an expected way
  regex_match = [paychex_formatted, ie11_formatted, just_date, just_date_backward].compact.first
  raise e unless regex_match.present?

  new_str = %w[year month day]
    .map { |component| regex_match[component] if regex_match.names.include?(component) }
    .compact
    .join("-")

  # If we end up with an unreasonable year, throw an error
  raise e unless new_str.split("-").first.to_i.between?(TranzitoUtils::DEFAULT[:earliest_year], TranzitoUtils::DEFAULT[:latest_year])
  # Add the day, if there isn't one
  new_str += "-01" unless regex_match.names.include?("day")
  # If it's paychex_formatted there is an hour and minute
  if paychex_formatted.present?
    new_str += " #{regex_match["hour"]}:#{regex_match["minute"]}#{regex_match["ampm"]}"
  end
  # Run it through TimeParser again
  parse(new_str, timezone_str)
end

.parse_timezone(timezone_str) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/tranzito_utils/services/time_parser.rb', line 47

def self.parse_timezone(timezone_str)
  return TranzitoUtils::DEFAULT[:time_zone] unless timezone_str.present?
  return timezone_str if timezone_str.is_a?(ActiveSupport::TimeZone) # in case we were given a timezone obj

  # tzinfo requires non-whitespaced strings, so try that if the normal lookup fails
  ActiveSupport::TimeZone[timezone_str] || ActiveSupport::TimeZone[timezone_str.strip.tr("\s", "_")]
end

.round(time, unit = "minute") ⇒ Object

Accepts a time object, rounds to minutes



56
57
58
# File 'lib/tranzito_utils/services/time_parser.rb', line 56

def self.round(time, unit = "minute")
  (unit == "second") ? time.change(usec: 0, sec: 0) : time.change(min: 0, usec: 0, sec: 0)
end