Class: CompositeUnitMeasurements::Time

Inherits:
Object
  • Object
show all
Defined in:
lib/composite_unit_measurements/time.rb

Overview

A parser handling time measurements, particularly for composite units like hour:minute:second,microsecond, minute-second, hour-minute, etc.

Author:

Since:

  • 0.2.0

Constant Summary collapse

HOUR_ALIASES =

Regex pattern for aliases of hour unit.

Author:

Since:

  • 0.3.0

/(?:h|hr|hour(?:s)?)/.freeze
MINUTE_ALIASES =

Regex pattern for aliases of minute unit.

Author:

Since:

  • 0.3.0

/(?:min|minute(?:s)?)/.freeze
SECOND_ALIASES =

Regex pattern for aliases of second unit.

Author:

Since:

  • 0.5.0

/(?:s|sec|second(?:s)?)/.freeze
MILLISECOND_ALIASES =

Regex pattern for aliases of millisecond unit.

Author:

Since:

  • 0.6.0

/(?:ms|millisec|millisecond(?:s)?)/.freeze
DAY_ALIASES =

Regex pattern for aliases of day unit.

Author:

Since:

  • 0.5.0

/(?:d|day(?:s)?)/.freeze
WEEK_ALIASES =

Regex pattern for aliases of week unit.

Author:

Since:

  • 0.5.0

/(?:wk|week(?:s)?)/.freeze
MONTH_ALIASES =

Regex pattern for aliases of month unit.

Author:

Since:

  • 0.5.0

/(?:mo|month(?:s)?)/.freeze
YEAR_ALIASES =

Regex pattern for aliases of year unit.

Author:

Since:

  • 0.6.0

/(?:y|yr|year(?:s)?)/.freeze
HOUR_MINUTE =

Regex pattern for parsing a time measurement in the format of hour-minute.

Author:

Since:

  • 0.3.0

/\A#{ANY_NUMBER}\s*#{HOUR_ALIASES}\s*#{ANY_NUMBER}\s*#{MINUTE_ALIASES}\z/.freeze
DURATION =

Regex pattern for parsing duration in the format of hour:minute:second or hour:minute:second,microsecond.

Author:

Since:

  • 0.2.0

/\A(?<hour>#{REAL_NUMBER}):(?<min>#{REAL_NUMBER}):(?:(?<sec>#{REAL_NUMBER}))?(?:,(?<msec>#{REAL_NUMBER}))?\z/.freeze
MINUTE_SECOND =

Regex pattern for parsing a time measurement in the format of minute-second.

Author:

Since:

  • 0.5.0

/\A#{ANY_NUMBER}\s*#{MINUTE_ALIASES}\s*#{ANY_NUMBER}\s*#{SECOND_ALIASES}\z/.freeze
WEEK_DAY =

Regex pattern for parsing a time measurement in the format of week-day.

Author:

Since:

  • 0.5.0

/\A#{ANY_NUMBER}\s*#{WEEK_ALIASES}\s*#{ANY_NUMBER}\s*#{DAY_ALIASES}\z/.freeze
MONTH_DAY =

Regex pattern for parsing a time measurement in the format of month-day.

Author:

Since:

  • 0.5.0

/\A#{ANY_NUMBER}\s*#{MONTH_ALIASES}\s*#{ANY_NUMBER}\s*#{DAY_ALIASES}\z/.freeze
SECOND_MILLISECOND =

Regex pattern for parsing a time measurement in the format of second-millisecond.

Author:

Since:

  • 0.6.0

/\A#{ANY_NUMBER}\s*#{SECOND_ALIASES}\s*#{ANY_NUMBER}\s*#{MILLISECOND_ALIASES}\z/.freeze
YEAR_MONTH =

Regex pattern for parsing a time measurement in the format of +year-month.

Author:

Since:

  • 0.6.0

/\A#{ANY_NUMBER}\s*#{YEAR_ALIASES}\s*#{ANY_NUMBER}\s*#{MONTH_ALIASES}\z/.freeze

Class Method Summary collapse

Class Method Details

.parse(string) ⇒ UnitMeasurements::Time

Parses a given string into a UnitMeasurements::Time object.

Examples:

Parse ‘hour-minute’ measurement:

CompositeUnitMeasurements::Time.parse("3 h 45 min") #=> 3.75 h

Parse ‘duration’:

CompositeUnitMeasurements::Time.parse("12:60:3600,360000000") #=> 14.1 h
CompositeUnitMeasurements::Time.parse("12:60:3600") #=> 14.0 h

Parse ‘minute-second’ measurement:

CompositeUnitMeasurements::Time.parse("10 min 90 s") #=> 11.5 min

Parse ‘week-day’ measurement:

CompositeUnitMeasurements::Time.parse("8 wk 3 d") #=> 8.428571428571429 wk

Parse ‘month-day’ measurement:

CompositeUnitMeasurements::Time.parse("2 mo 60 d") #=> 3.97260057797197 mo

Parse ‘second-millisecond’ measurement:

CompositeUnitMeasurements::Time.parse("8 s 500 ms") #=> 8.5 s

Parse ‘year-month’ measurement:

CompositeUnitMeasurements::Time.parse("3 yr 4 mo") #=> 3.333333698630137 yr

Parameters:

  • string (String)

    The string to parse for time measurement.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

Raises:

  • (UnitMeasurements::ParseError)

    If the string does not match any known format.

Author:

Since:

  • 0.2.0



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/composite_unit_measurements/time.rb', line 41

def parse(string)
  case string
  when HOUR_MINUTE        then parse_hour_minute(string)
  when DURATION           then parse_duration(string)
  when MINUTE_SECOND      then parse_minute_second(string)
  when WEEK_DAY           then parse_week_day(string)
  when MONTH_DAY          then parse_month_day(string)
  when SECOND_MILLISECOND then parse_second_millisecond(string)
  when YEAR_MONTH         then parse_year_month(string)
  else                         raise UnitMeasurements::ParseError, string
  end
end

.parse_duration(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing time duration in the format of hour:minute:second,microsecond or hour:minute:second into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time duration.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

Raises:

  • (ArgumentError)

    Raises an ArgumentError for an invalid duration format.

See Also:

Author:

Since:

  • 0.2.0



90
91
92
93
94
95
96
97
98
# File 'lib/composite_unit_measurements/time.rb', line 90

def parse_duration(string)
  hour, minute, second, microsecond = string.match(DURATION)&.captures
  raise ArgumentError, "Invalid Duration" if [hour, minute, second, microsecond].all?(&:nil?)

  UnitMeasurements::Time.new((hour || 0), "h") +
    UnitMeasurements::Time.new((minute || 0), "min") +
    UnitMeasurements::Time.new((second || 0), "s") +
    UnitMeasurements::Time.new((microsecond || 0), "μs")
end

.parse_hour_minute(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of hour-minute into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of hour-minute.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.3.0



68
69
70
71
72
73
74
# File 'lib/composite_unit_measurements/time.rb', line 68

def parse_hour_minute(string)
  hour, minute = string.match(HOUR_MINUTE)&.captures

  if hour && minute
    UnitMeasurements::Time.new(hour, "h") + UnitMeasurements::Time.new(minute, "min")
  end
end

.parse_minute_second(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of minute-second into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of minute-second.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.5.0



112
113
114
115
116
117
118
# File 'lib/composite_unit_measurements/time.rb', line 112

def parse_minute_second(string)
  minute, second = string.match(MINUTE_SECOND)&.captures

  if minute && second
    UnitMeasurements::Time.new(minute, "min") + UnitMeasurements::Time.new(second, "s")
  end
end

.parse_month_day(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of month-day into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of month-day.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.5.0



152
153
154
155
156
157
158
# File 'lib/composite_unit_measurements/time.rb', line 152

def parse_month_day(string)
  month, day = string.match(MONTH_DAY)&.captures

  if month && day
    UnitMeasurements::Time.new(month, "mo") + UnitMeasurements::Time.new(day, "d")
  end
end

.parse_second_millisecond(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of second-millisecond into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of second-millisecond.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.6.0



172
173
174
175
176
177
178
# File 'lib/composite_unit_measurements/time.rb', line 172

def parse_second_millisecond(string)
  second, millisecond = string.match(SECOND_MILLISECOND)&.captures

  if second && millisecond
    UnitMeasurements::Time.new(second, "s") + UnitMeasurements::Time.new(millisecond, "ms")
  end
end

.parse_week_day(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of week-day into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of week-day.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.5.0



132
133
134
135
136
137
138
# File 'lib/composite_unit_measurements/time.rb', line 132

def parse_week_day(string)
  week, day = string.match(WEEK_DAY)&.captures

  if week && day
    UnitMeasurements::Time.new(week, "wk") + UnitMeasurements::Time.new(day, "d")
  end
end

.parse_year_month(string) ⇒ UnitMeasurements::Time (private)

Parses a string representing a time in the format of year-month into a UnitMeasurements::Time object.

Parameters:

  • string (String)

    The string representing time measurement in the format of year-month.

Returns:

  • (UnitMeasurements::Time)

    Returns a UnitMeasurements::Time object if parsing is successful.

See Also:

Author:

Since:

  • 0.6.0



192
193
194
195
196
197
198
# File 'lib/composite_unit_measurements/time.rb', line 192

def parse_year_month(string)
  year, month = string.match(YEAR_MONTH)&.captures

  if year && month
    UnitMeasurements::Time.new(year, "yr") + UnitMeasurements::Time.new(month, "mo")
  end
end