Class: Runby::RunbyTime

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/runby_pace/runby_time.rb

Overview

Represents a human-readable time in the format MM:ss

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(time) ⇒ RunbyTime

Returns a new instance of RunbyTime.



17
18
19
20
# File 'lib/runby_pace/runby_time.rb', line 17

def initialize(time)
  init_from_parts time if time.is_a? RunbyTimeParser::TimeParts
  freeze
end

Instance Attribute Details

#hours_partObject (readonly)

Returns the value of attribute hours_part.



8
9
10
# File 'lib/runby_pace/runby_time.rb', line 8

def hours_part
  @hours_part
end

#minutes_partObject (readonly)

Returns the value of attribute minutes_part.



8
9
10
# File 'lib/runby_pace/runby_time.rb', line 8

def minutes_part
  @minutes_part
end

#seconds_partObject (readonly)

Returns the value of attribute seconds_part.



8
9
10
# File 'lib/runby_pace/runby_time.rb', line 8

def seconds_part
  @seconds_part
end

#time_sObject (readonly)

Returns the value of attribute time_s.



8
9
10
# File 'lib/runby_pace/runby_time.rb', line 8

def time_s
  @time_s
end

Class Method Details

.check_5k_sanity(time) ⇒ Object



59
60
61
62
63
# File 'lib/runby_pace/runby_time.rb', line 59

def self.check_5k_sanity(time)
  return unless time.is_a? RunbyTime
  return '5K times of less than 14:00 are unlikely' if time.minutes_part < 14
  return '5K times of greater than 42:00 are not fully supported' if time.total_seconds > (42 * 60)
end

.from_hours(total_hours) ⇒ Object

Parameters:

  • total_hours (numeric)


40
41
42
# File 'lib/runby_pace/runby_time.rb', line 40

def self.from_hours(total_hours)
  from_seconds(total_hours * 60.0 * 60.0)
end

.from_minutes(total_minutes) ⇒ Object

Parameters:

  • total_minutes (numeric)


35
36
37
# File 'lib/runby_pace/runby_time.rb', line 35

def self.from_minutes(total_minutes)
  from_seconds(total_minutes * 60.0)
end

.from_seconds(total_seconds) ⇒ Object

Parameters:

  • total_seconds (numeric)


23
24
25
26
27
28
29
30
31
32
# File 'lib/runby_pace/runby_time.rb', line 23

def self.from_seconds(total_seconds)
  hours = total_seconds.abs.to_i / 60 / 60
  minutes = (total_seconds.abs.to_i / 60) % 60
  seconds = total_seconds.abs.to_i % 60
  if hours.positive?
    RunbyTime.new format('%d:%02d:%02d', hours, minutes, seconds)
  else
    RunbyTime.new format('%02d:%02d', minutes, seconds)
  end
end

.new(time) ⇒ Object



10
11
12
13
14
15
# File 'lib/runby_pace/runby_time.rb', line 10

def self.new(time)
  return time if time.is_a? RunbyTime
  return RunbyTime.parse time if time.is_a?(String) || time.is_a?(Symbol)
  return from_minutes(time) if time.is_a? Numeric
  super
end

.parse(str) ⇒ Object



44
45
46
# File 'lib/runby_pace/runby_time.rb', line 44

def self.parse(str)
  RunbyTimeParser.parse str
end

.try_parse(str, is_five_k = false) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/runby_pace/runby_time.rb', line 48

def self.try_parse(str, is_five_k = false)
  time, error_message, warning_message = nil
  begin
    time = parse str
  rescue StandardError => ex
    error_message = "#{ex.message} (#{str})"
  end
  warning_message = check_5k_sanity(time) if !time.nil? && is_five_k
  { time: time, error: error_message, warning: warning_message }
end

Instance Method Details

#*(other) ⇒ RunbyTime

Parameters:

  • other (Numeric)

Returns:



95
96
97
98
# File 'lib/runby_pace/runby_time.rb', line 95

def *(other)
  raise "Cannot multiply Runby::RunbyTime with a #{other.class}" unless other.is_a?(Numeric)
  RunbyTime.from_minutes(total_minutes * other)
end

#+(other) ⇒ Object

Parameters:



88
89
90
91
# File 'lib/runby_pace/runby_time.rb', line 88

def +(other)
  raise "Cannot add Runby::RunbyTime to a #{other.class}" unless other.is_a?(RunbyTime)
  RunbyTime.from_seconds(total_seconds + other.total_seconds)
end

#-(other) ⇒ Object

Parameters:



82
83
84
85
# File 'lib/runby_pace/runby_time.rb', line 82

def -(other)
  raise "Cannot subtract #{other.class} from a Runby::RunbyTime" unless other.is_a?(RunbyTime)
  RunbyTime.from_seconds(total_seconds - other.total_seconds)
end

#/(other) ⇒ Numeric, RunbyTime

Parameters:

Returns:



102
103
104
105
106
107
108
109
110
# File 'lib/runby_pace/runby_time.rb', line 102

def /(other)
  raise "Cannot divide Runby::RunbyTime by #{other.class}" unless other.is_a?(RunbyTime) || other.is_a?(Numeric)
  case other
  when RunbyTime
    total_seconds / other.total_seconds
  when Numeric
    RunbyTime.from_seconds(total_seconds / other)
  end
end

#<=>(other) ⇒ Object



112
113
114
115
116
117
118
119
120
# File 'lib/runby_pace/runby_time.rb', line 112

def <=>(other)
  raise "Unable to compare Runby::RunbyTime to #{other.class}(#{other})" unless [RunbyTime, String].include? other.class
  if other.is_a? RunbyTime
    total_seconds <=> other.total_seconds
  elsif other.is_a? String
    return 0 if @time_s == other
    total_seconds <=> RunbyTime.parse(other).total_seconds
  end
end

#almost_equals?(other_time, tolerance_time = '00:01') ⇒ Boolean

Returns:

  • (Boolean)


122
123
124
125
126
# File 'lib/runby_pace/runby_time.rb', line 122

def almost_equals?(other_time, tolerance_time = '00:01')
  other_time = RunbyTime.new(other_time) if other_time.is_a?(String)
  tolerance = RunbyTime.new(tolerance_time)
  self >= (other_time - tolerance) && self <= (other_time + tolerance)
end

#to_sObject



65
66
67
# File 'lib/runby_pace/runby_time.rb', line 65

def to_s
  @time_s
end

#total_hoursObject



69
70
71
# File 'lib/runby_pace/runby_time.rb', line 69

def total_hours
  @hours_part + (@minutes_part / 60.0) + (@seconds_part / 60.0 / 60.0)
end

#total_minutesObject



77
78
79
# File 'lib/runby_pace/runby_time.rb', line 77

def total_minutes
  @hours_part * 60 + @minutes_part + (@seconds_part / 60.0)
end

#total_secondsObject



73
74
75
# File 'lib/runby_pace/runby_time.rb', line 73

def total_seconds
  @hours_part * 60 * 60 + @minutes_part * 60 + @seconds_part
end