Class: Duration
- Includes:
- Comparable, Enumerable
- Defined in:
- lib/more/facets/duration.rb
Overview
Duration
Duration is a simple class that provides ways of easily manipulating durations
(timespans) and formatting them as well.
Usage:
require 'duration'
=> true
d = Duration.new(60 * 60 * 24 * 10 + 120 + 30)
=> #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
d.to_s
=> "1 week, 3 days, 2 minutes and 30 seconds"
[d.weeks, d.days]
=> [1, 3]
d.days = 7; d
=> #<Duration: 2 weeks, 2 minutes and 30 seconds>
d.strftime('%w w, %d d, %h h, %m m, %s s')
=> "2 w, 0 d, 0 h, 2 m, 30 s"
Direct Known Subclasses
Constant Summary collapse
- WEEK =
60 * 60 * 24 * 7
- DAY =
60 * 60 * 24
- HOUR =
60 * 60
- MINUTE =
60- SECOND =
1
Instance Attribute Summary collapse
-
#days ⇒ Object
Returns the value of attribute days.
-
#hours ⇒ Object
Returns the value of attribute hours.
-
#minutes ⇒ Object
Returns the value of attribute minutes.
-
#total ⇒ Object
(also: #to_i)
readonly
Returns the value of attribute total.
-
#weeks ⇒ Object
Returns the value of attribute weeks.
Instance Method Summary collapse
-
#*(other) ⇒ Object
Multiply two Durations.
-
#+(other) ⇒ Object
Add to Duration.
-
#-(other) ⇒ Object
Subtract from Duration.
-
#/(other) ⇒ Object
Divide two Durations.
-
#<=>(other) ⇒ Object
Calls ‘<=>’ on Duration#total.
-
#each ⇒ Object
For iterating through the duration set of weeks, days, hours, minutes, and seconds.
-
#initialize(seconds_or_attr = 0) ⇒ Duration
constructor
Initialize Duration class.
-
#inspect ⇒ Object
Inspection string–Similar to #to_s except that it has the class name.
-
#seconds(part = nil) ⇒ Object
Get the number of seconds of a given part, or simply just get the number of seconds.
-
#seconds=(n) ⇒ Object
Set the number of minutes.
-
#strftime(fmt) ⇒ Object
Format duration.
-
#to_s ⇒ Object
Friendly, human-readable string representation of the duration.
Methods included from Enumerable
#**, #accumulate, cart, cartesian_product, #cartesian_product, #cluster_by, #collect_if, #collect_with_index, combinations, #combos, #commonality, #compact_collect, #count, #divide, #each_by, #each_combination, #each_combo, #each_pair, #each_permutation, #eachn, #elementwise, #entropy, #every, #every!, #filter_collect, #frequency, #group_by, #ideal_entropy, #inject!, #injecting, #map_send, #mash, #mode, #modulate, #none?, #nonuniq, #occur, #one?, #permutation, #permutation_number, #probability, #split, #sum, #threaded_map, #threaded_map_send, #to_elem, #to_h, #to_hash, #uniq_by
Methods included from Comparable
#at_least, #at_most, #cap, #clip, #cmp
Constructor Details
#initialize(seconds_or_attr = 0) ⇒ Duration
Initialize Duration class.
Example
d = Duration.new(60 * 60 * 24 * 10 + 120 + 30)
=> #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
d = Duration.new(:weeks => 1, :days => 3, :minutes => 2, :seconds => 30)
=> #<Duration: 1 week, 3 days, 2 minutes and 30 seconds>
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/more/facets/duration.rb', line 65 def initialize(seconds_or_attr = 0) if seconds_or_attr.kind_of? Hash # Part->time map table. h = {:weeks => WEEK, :days => DAY, :hours => HOUR, :minutes => MINUTE, :seconds => SECOND} # Loop through each valid part, ignore all others. seconds = seconds_or_attr.inject(0) do |sec, args| # Grab the part of the duration (week, day, whatever) and the number of seconds for it. part, time = args # Map each part to their number of seconds and the given value. # {:weeks => 2} maps to h[:weeks] -- so... weeks = WEEK * 2 if h.key?(prt = part.to_s.to_sym) then sec + time * h[prt] else 0 end end else seconds = seconds_or_attr end @total, array = seconds.to_f.round, [] @seconds = [WEEK, DAY, HOUR, MINUTE].inject(@total) do |left, part| array << left / part; left % part end @weeks, @days, @hours, @minutes = array end |
Instance Attribute Details
#days ⇒ Object
Returns the value of attribute days.
48 49 50 |
# File 'lib/more/facets/duration.rb', line 48 def days @days end |
#hours ⇒ Object
Returns the value of attribute hours.
48 49 50 |
# File 'lib/more/facets/duration.rb', line 48 def hours @hours end |
#minutes ⇒ Object
Returns the value of attribute minutes.
48 49 50 |
# File 'lib/more/facets/duration.rb', line 48 def minutes @minutes end |
#total ⇒ Object (readonly) Also known as: to_i
Returns the value of attribute total.
48 49 50 |
# File 'lib/more/facets/duration.rb', line 48 def total @total end |
#weeks ⇒ Object
Returns the value of attribute weeks.
48 49 50 |
# File 'lib/more/facets/duration.rb', line 48 def weeks @weeks end |
Instance Method Details
#*(other) ⇒ Object
Multiply two Durations.
Example
d = Duration.new(30)
=> #<Duration: 30 seconds>
d * 2
=> #<Duration: 1 minute>
326 327 328 |
# File 'lib/more/facets/duration.rb', line 326 def *(other) self.class.new(@total * other.to_i) end |
#+(other) ⇒ Object
Add to Duration.
Example
d = Duration.new(30)
=> #<Duration: 30 seconds>
d + 30
=> #<Duration: 1 minute>
300 301 302 |
# File 'lib/more/facets/duration.rb', line 300 def +(other) self.class.new(@total + other.to_i) end |
#-(other) ⇒ Object
Subtract from Duration.
Example
d = Duration.new(30)
=> #<Duration: 30 seconds>
d - 15
=> #<Duration: 15 seconds>
313 314 315 |
# File 'lib/more/facets/duration.rb', line 313 def -(other) self.class.new(@total - other.to_i) end |
#/(other) ⇒ Object
Divide two Durations.
Example
d = Duration.new(30)
=> #<Duration: 30 seconds>
d / 2
=> #<Duration: 15 seconds>
339 340 341 |
# File 'lib/more/facets/duration.rb', line 339 def /(other) self.class.new(@total / other.to_i) end |
#<=>(other) ⇒ Object
Calls ‘<=>’ on Duration#total.
Example
5.days == 24.hours * 5
=> true
188 189 190 |
# File 'lib/more/facets/duration.rb', line 188 def <=>(other) @total <=> other.to_i end |
#each ⇒ Object
For iterating through the duration set of weeks, days, hours, minutes, and seconds.
Example
Duration.new(:weeks => 1, :seconds => 30).each do |part, time|
puts "part: #{part}, time: #{time}"
end
Output
part: weeks, time: 1
part: days, time: 0
part: hours, time: 0
part: minutes, time: 0
part: seconds, time: 30
170 171 172 173 174 175 176 177 178 179 |
# File 'lib/more/facets/duration.rb', line 170 def each [['weeks' , @weeks ], ['days' , @days ], ['hours' , @hours ], ['minutes' , @minutes], ['seconds' , @seconds]].each do |part, time| # Yield to block yield part, time end end |
#inspect ⇒ Object
Inspection string–Similar to #to_s except that it has the class name.
Example
Duration.new(:seconds => 140)
=> #<Duration: 2 minutes and 20 seconds>
287 288 289 |
# File 'lib/more/facets/duration.rb', line 287 def inspect "#<#{self.class}: #{(s = to_s).empty? ? '...' : s}>" end |
#seconds(part = nil) ⇒ Object
Get the number of seconds of a given part, or simply just get the number of seconds.
Example
d = Duration.new(:weeks => 1, :days => 1, :hours => 1, :seconds => 30)
=> #<Duration: 1 week, 1 day, 1 hour and 30 seconds>
d.seconds(:weeks)
=> 604800
d.seconds(:days)
=> 86400
d.seconds(:hours)
=> 3600
d.seconds
=> 30
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/more/facets/duration.rb', line 142 def seconds(part = nil) # Table mapping h = {:weeks => WEEK, :days => DAY, :hours => HOUR, :minutes => MINUTE} if [:weeks, :days, :hours, :minutes].include? part __send__(part) * h[part] else @seconds end end |
#seconds=(n) ⇒ Object
Set the number of minutes.
Example
d = Duration.new(0)
=> #<Duration: ...>
d.seconds = 30; d
=> #<Duration: 30 seconds>
253 254 255 |
# File 'lib/more/facets/duration.rb', line 253 def seconds=(n) initialize(:seconds => (@total + n) - @seconds) 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!"
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/more/facets/duration.rb', line 111 def strftime(fmt) h =\ {'w' => @weeks , 'd' => @days , 'h' => @hours , 'm' => @minutes, 's' => @seconds, 't' => @total , 'x' => to_s} fmt.gsub(/%?%(w|d|h|m|s|t|x)/) do |match| match.size == 3 ? match : h[match[1..1]] end.gsub('%%', '%') end |
#to_s ⇒ Object
Friendly, human-readable string representation of the duration.
Example
d = Duration.new(:seconds => 140)
=> #<Duration: 2 minutes and 20 seconds>
d.to_s
=> "2 minutes and 20 seconds"
266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/more/facets/duration.rb', line 266 def to_s str = '' each do |part, time| # Skip any zero times. next if time.zero? # Concatenate the part of the time and the time itself. str << "#{time} #{time == 1 ? part[0..-2] : part}, " end str.chomp(', ').sub(/(.+), (.+)/, '\1 and \2') end |