Class: Tins::Duration

Inherits:
Object show all
Includes:
Comparable
Defined in:
lib/tins/duration.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seconds) ⇒ Duration

Returns a new instance of Duration.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/tins/duration.rb', line 47

def initialize(seconds)
  @negative = seconds < 0
  seconds = seconds.abs
  @original_seconds = seconds
  @days, @hours, @minutes, @seconds, @fractional_seconds =
    [ 86_400, 3600, 60, 1, 0 ].inject([ [], seconds ]) {|(r, s), d|
      if d > 0
        dd, rest = s.divmod(d)
        r << dd
        [ r, rest ]
      else
        r << s
      end
    }
end

Class Method Details

.parse(string, template: '%S%d+%h:%m:%s.%f') ⇒ Integer, Float

Returns the number of seconds represented by the given duration string according to the provided template format.

Examples:

Tins::Duration.parse('6+05:04:03', template: '%S%d+%h:%m:%s') # => 536643
Tins::Duration.parse('6+05:04:03.21', template: '%S%d+%h:%m:%s.%f') # => 536643.21

Parameters:

  • string (String)

    The duration string to parse.

  • template (String) (defaults to: '%S%d+%h:%m:%s.%f')

    for the duration format, see #format.

Returns:

  • (Integer, Float)

    The number of (fractional) seconds of the duration.



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/tins/duration.rb', line 16

def self.parse(string, template: '%S%d+%h:%m:%s.%f')
  s, t = string.to_s.dup, template.dup
  d, sd = 0, 1
  loop do
    t.sub!(/\A(%[Sdhmsf%]|.)/) { |directive|
      case directive
      when '%S' then s.sub!(/\A-?/)   { sd *= -1 if _1 == ?-; '' }
      when '%d' then s.sub!(/\A\d+/)  { d += 86_400 * _1.to_i; '' }
      when '%h' then s.sub!(/\A\d+/)  { d += 3_600 * _1.to_i; '' }
      when '%m' then s.sub!(/\A\d+/)  { d += 60 * _1.to_i; '' }
      when '%s' then s.sub!(/\A\d+/)  { d += _1.to_i; '' }
      when '%f' then s.sub!(/\A\d+/)  { d += Float(?. + _1); '' }
      when '%%' then
        if s[0] == ?%
          s[0] = ''
        else
          raise "expected %s, got #{s.inspect}"
        end
      else
        if directive == s[0]
          s[0] = ''
        else
          raise ArgumentError, "expected #{t.inspect}, got #{s.inspect}"
        end
      end
      ''
    } or break
  end
  sd * d
end

Instance Method Details

#<=>(other) ⇒ Object



67
68
69
# File 'lib/tins/duration.rb', line 67

def <=>(other)
  to_f <=> other.to_f
end

#days?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/tins/duration.rb', line 75

def days?
  @days > 0
end

#format(template = '%S%d+%h:%m:%s.%f', precision: nil) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tins/duration.rb', line 95

def format(template = '%S%d+%h:%m:%s.%f', precision: nil)
  result = template.gsub(/%[DdhmSs]/) { |directive|
    case directive
    when '%S' then ?- if negative?
    when '%d' then @days
    when '%h' then '%02u' % @hours
    when '%m' then '%02u' % @minutes
    when '%s' then '%02u' % @seconds
    when '%D' then format_smart
    end
  }
  if result.include?('%f')
    if precision
      fractional_seconds = "%.#{precision}f" % @fractional_seconds
    else
      fractional_seconds = '%f' % @fractional_seconds
    end
    result.gsub!('%f', fractional_seconds[2..-1])
  end
  result
end

#fractional_seconds?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/tins/duration.rb', line 91

def fractional_seconds?
  @fractional_seconds > 0
end

#hours?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/tins/duration.rb', line 79

def hours?
  @hours > 0
end

#minutes?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/tins/duration.rb', line 83

def minutes?
  @minutes > 0
end

#negative?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/tins/duration.rb', line 71

def negative?
  @negative
end

#seconds?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/tins/duration.rb', line 87

def seconds?
  @seconds > 0
end

#to_fObject



63
64
65
# File 'lib/tins/duration.rb', line 63

def to_f
  @original_seconds.to_f
end

#to_sObject



117
118
119
# File 'lib/tins/duration.rb', line 117

def to_s
  format_smart
end