Class: Duration

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

Overview

Author: Stefano Harding <[email protected]> License: Apache License, Version 2.0 Copyright: © 2014-2015 Stefano Harding

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Defined Under Namespace

Modules: Numeric, Time

Constant Summary collapse

SECOND =
1
MINUTE =
60 * SECOND
HOUR =
60 * MINUTE
DAY =
24 * HOUR
WEEK =
7 * DAY
YEAR =
365 * DAY
SEGMENTS =
%w{years weeks days hours minutes seconds}.collect{ |s| s.to_sym }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seconds = 0, *segments) ⇒ Duration

Returns a new instance of Duration.



36
37
38
39
# File 'lib/garcon/core_ext/duration.rb', line 36

def initialize(seconds=0, *segments)
  @seconds = seconds.to_i
  reset_segments(*segments)
end

Class Method Details

.[](seconds, *segments) ⇒ Object



32
33
34
# File 'lib/garcon/core_ext/duration.rb', line 32

def self.[](seconds, *segments)
  new(seconds, *segments)
end

Instance Method Details

#*(other) ⇒ Object



135
136
137
# File 'lib/garcon/core_ext/duration.rb', line 135

def *(other)
  self.class.new(@seconds * other.to_i, segments)
end

#+(other) ⇒ Object



127
128
129
# File 'lib/garcon/core_ext/duration.rb', line 127

def +(other)
  self.class.new(@seconds + other.to_i, segments)
end

#+@Object



188
189
190
# File 'lib/garcon/core_ext/duration.rb', line 188

def +@
  self.class.new(+@seconds)
end

#-(other) ⇒ Object



131
132
133
# File 'lib/garcon/core_ext/duration.rb', line 131

def -(other)
  self.class.new(@seconds - other.to_i, segments)
end

#-@Object



184
185
186
# File 'lib/garcon/core_ext/duration.rb', line 184

def -@
  self.class.new(-@seconds)
end

#/(other) ⇒ Object



139
140
141
# File 'lib/garcon/core_ext/duration.rb', line 139

def /(other)
  self.class.new(@seconds / other.to_i, segments)
end

#<=>(other) ⇒ Object



114
115
116
# File 'lib/garcon/core_ext/duration.rb', line 114

def <=>(other)
  @seconds <=> other.to_i
end

#==(other) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/garcon/core_ext/duration.rb', line 106

def ==(other)
  if Duration === other
    other.seconds == seconds
  else
    other == seconds
  end
end

#after(time) ⇒ Object



196
197
198
# File 'lib/garcon/core_ext/duration.rb', line 196

def after(time)
  @seconds.after(time)
end

#before(time) ⇒ Object



192
193
194
# File 'lib/garcon/core_ext/duration.rb', line 192

def before(time)
  @seconds.before(time)
end

#daysObject



120
# File 'lib/garcon/core_ext/duration.rb', line 120

def days    ; to_h[:days]    ; end

#hoursObject



121
# File 'lib/garcon/core_ext/duration.rb', line 121

def hours   ; to_h[:hours]   ; end

#inspectObject



65
66
67
68
69
70
# File 'lib/garcon/core_ext/duration.rb', line 65

def inspect
  h = to_h
  segments.reverse.collect do |l|
    "#{h[l.to_sym]} #{l}"
  end.join(' ')
end

#minutesObject



122
# File 'lib/garcon/core_ext/duration.rb', line 122

def minutes ; to_h[:minutes] ; end

#reset_segments(*segments) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/garcon/core_ext/duration.rb', line 43

def reset_segments(*segments)
  case segments.size
  when 0
    @segments = [:days, :hours, :minutes, :seconds]
  when 1
    case segments = segments[0]
    when Array
      @segments = segments.collect { |p| (p.to_s.downcase.chomp('s') + 's').to_sym }
      raise ArgumentError unless @segments.all? { |s| SEGMENTS.include?(s) }
    else
      f = SEGMENTS.index(segments)
      @segments = SEGMENTS[f..0]
    end
  when 2
    f = SEGMENTS.index(segments[0])
    t = SEGMENTS.index(segments[1])
    @segments = SEGMENTS[f..t]
  else
    raise ArgumentError
  end
end

#secondsObject



123
# File 'lib/garcon/core_ext/duration.rb', line 123

def seconds ; to_h[:seconds] ; end

#segmented(*segments) ⇒ Object



143
144
145
# File 'lib/garcon/core_ext/duration.rb', line 143

def segmented(*segments)
  self.class.new(@seconds, segments)
end

#segmentsObject



41
# File 'lib/garcon/core_ext/duration.rb', line 41

def segments; @segments; end

#strftime(fmt) ⇒ Object

Format duration.

Identifiers

%w -- Number of weeks
%d -- Number of days
%h -- Number of hours
%m -- Number of minutes
%s -- Number of seconds
%t -- Total number of seconds
%x -- Duration#to_s
%% -- Literal `%' character

Example

d = Duration.new(:weeks => 10, :days => 7)
=> #<Duration: 11 weeks>
d.strftime("It's been %w weeks!")
=> "It's been 11 weeks!"


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/garcon/core_ext/duration.rb', line 167

def strftime(fmt)
  h = to_h
  hx = {
   'y' => h[:years]  ,
   'w' => h[:weeks]  ,
   'd' => h[:days]   ,
   'h' => h[:hours]  ,
   'm' => h[:minutes],
   's' => h[:seconds],
   't' => total,
   'x' => to_s
  }
  fmt.gsub(/%?%(w|d|h|m|s|t|x)/) do |match|
    hx[match[1..1]]
  end.gsub('%%', '%')
end

#to_aObject



77
78
79
80
81
82
83
84
85
86
# File 'lib/garcon/core_ext/duration.rb', line 77

def to_a
  a, s = [], @seconds
  a[5], s = *s.divmod(YEAR)   if @segments.include?(:years)
  a[4], s = *s.divmod(WEEK)   if @segments.include?(:weeks)
  a[3], s = *s.divmod(DAY)    if @segments.include?(:days)
  a[2], s = *s.divmod(HOUR)   if @segments.include?(:hours)
  a[1], s = *s.divmod(MINUTE) if @segments.include?(:minutes)
  a[0], s = *s.divmod(SECOND) if @segments.include?(:seconds)
  a.compact.reverse
end

#to_fObject



73
# File 'lib/garcon/core_ext/duration.rb', line 73

def to_f ; @seconds.to_f ; end

#to_hObject



88
89
90
91
92
93
94
95
96
97
# File 'lib/garcon/core_ext/duration.rb', line 88

def to_h
  h, s = {}, @seconds
  h[:years],   s = *s.divmod(YEAR)   if @segments.include?(:years)
  h[:weeks],   s = *s.divmod(WEEK)   if @segments.include?(:weeks)
  h[:days],    s = *s.divmod(DAY)    if @segments.include?(:days)
  h[:hours],   s = *s.divmod(HOUR)   if @segments.include?(:hours)
  h[:minutes], s = *s.divmod(MINUTE) if @segments.include?(:minutes)
  h[:seconds], s = *s.divmod(SECOND) if @segments.include?(:seconds)
  h
end

#to_iObject



72
# File 'lib/garcon/core_ext/duration.rb', line 72

def to_i ; @seconds.to_i ; end

#to_sObject



99
100
101
102
103
104
# File 'lib/garcon/core_ext/duration.rb', line 99

def to_s
  h = to_h
  segments.reverse.collect do |l|
    "#{h[l.to_sym]} #{l}"
  end.join(' ')
end

#totalObject



125
# File 'lib/garcon/core_ext/duration.rb', line 125

def total ; seconds ; end

#weeksObject



119
# File 'lib/garcon/core_ext/duration.rb', line 119

def weeks   ; to_h[:weeks]   ; end

#yearsObject



118
# File 'lib/garcon/core_ext/duration.rb', line 118

def years   ; to_h[:years]   ; end