Class: Duration

Inherits:
Object
  • Object
show all
Includes:
Comparable, Enumerable
Defined in:
lib/duration.rb,
lib/duration/locale.rb,
lib/duration/version.rb,
lib/duration/holidays.rb,
lib/duration/localizations.rb,
lib/duration/localizations/korean.rb,
lib/duration/localizations/english.rb

Overview

Duration objects are simple mechanisms that allow you to operate on durations of time. They allow you to know how much time has passed since a certain point in time, or they can tell you how much time something is (when given as seconds) in different units of time measurement. Durations would particularly be useful for those scripts or applications that allow you to know the uptime of themselves or perhaps provide a countdown until a certain event.

Defined Under Namespace

Modules: Localizations Classes: Locale, LocaleError

Constant Summary collapse

MULTIPLES =

Unit multiples

{
  :seconds => 1,
  :minutes => 60,
  :hours   => 3600,
  :days    => 86400,
  :weeks   => 604800,
  :second  => 1,
  :minute  => 60,
  :hour    => 3600,
  :day     => 86400,
  :week    => 604800
}
UNITS =

Unit names

[:seconds, :minutes, :hours, :days, :weeks]
VERSION =

Duration library version number

'0.1.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = 0) ⇒ Duration

Initialize a duration. ‘args’ can be a hash or anything else. If a hash is passed, it will be scanned for a key=>value pair of time units such as those listed in the Duration::UNITS array or Duration::MULTIPLES hash.

If anything else except a hash is passed, #to_i is invoked on that object and expects that it return the number of seconds desired for the duration.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/duration.rb', line 56

def initialize(args = 0)
  # Two types of arguments are accepted.  If it isn't a hash, it's converted
  # to an integer.
  if args.kind_of?(Hash)
    @seconds = 0
    MULTIPLES.each do |unit, multiple|
      unit = unit.to_sym
      @seconds += args[unit] * multiple if args.key?(unit)
    end
  else
    @seconds = args.to_i
  end
  
  # Calculate duration
  calculate!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# File 'lib/duration.rb', line 141

def method_missing(m, *args, &block)
  units = UNITS.join('|')
  match = /(round_)?(#{units})_to_(#{units})$/.match(m.to_s)
  if match
    seconds = ((__send__(match[2].to_sym) * MULTIPLES[match[2].to_sym]) / MULTIPLES[match[3].to_sym].to_f)
    match[1] ? seconds.round : seconds
  else
    super
  end
end

Instance Attribute Details

#daysObject

Returns the value of attribute days.



34
35
36
# File 'lib/duration.rb', line 34

def days
  @days
end

#hoursObject

Returns the value of attribute hours.



34
35
36
# File 'lib/duration.rb', line 34

def hours
  @hours
end

#minutesObject

Returns the value of attribute minutes.



34
35
36
# File 'lib/duration.rb', line 34

def minutes
  @minutes
end

#secondsObject

Returns the value of attribute seconds.



34
35
36
# File 'lib/duration.rb', line 34

def seconds
  @seconds
end

#totalObject (readonly) Also known as: to_i

Returns the value of attribute total.



34
35
36
# File 'lib/duration.rb', line 34

def total
  @total
end

#weeksObject

Returns the value of attribute weeks.



34
35
36
# File 'lib/duration.rb', line 34

def weeks
  @weeks
end

Class Method Details

.change_locale(locale) ⇒ Object

Change the locale Duration will use when converting itself to a string



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

def Duration.change_locale(locale)
  @@locale = Localizations.locales[locale.to_sym] or raise LocaleError, "undefined locale '#{locale}'"
end

.since_epochObject

Constructs a Duration instance that represents the duration since the UNIX epoch (1970-01-01T00:00:00Z)



46
47
48
# File 'lib/duration.rb', line 46

def Duration.since_epoch
  new(Time.now)
end

.versionObject

Duration library version number



6
7
8
# File 'lib/duration/version.rb', line 6

def Duration.version
  VERSION
end

Instance Method Details

#%(other) ⇒ Object



178
179
180
# File 'lib/duration.rb', line 178

def %(other)
	Duration.new(@total % other.to_i)
end

#*(other) ⇒ Object



170
171
172
# File 'lib/duration.rb', line 170

def *(other)
	Duration.new(@total * other.to_i)
end

#+(other) ⇒ Object



162
163
164
# File 'lib/duration.rb', line 162

def +(other)
	Duration.new(@total + other.to_i)
end

#-(other) ⇒ Object



166
167
168
# File 'lib/duration.rb', line 166

def -(other)
	Duration.new(@total - other.to_i)
end

#/(other) ⇒ Object



174
175
176
# File 'lib/duration.rb', line 174

def /(other)
	Duration.new(@total / other.to_i)
end

#<=>(other) ⇒ Object

Compare this duration to another (or objects that respond to #to_i)



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

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

#calculate!Object

Calculates the duration from seconds and figures out what the actual durations are in specific units. This method is called internally, and does not need to be called by user code.



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

def calculate!
multiples = [MULTIPLES[:weeks], MULTIPLES[:days], MULTIPLES[:hours], MULTIPLES[:minutes], MULTIPLES[:seconds]]
units     = []
@total    = @seconds.to_f.round
multiples.inject(@total) do |total, multiple|
  # Divide into largest unit
	units << total / multiple
	total % multiple # The remainder will be divided as the next largest
end

# Gather the divided units
@weeks, @days, @hours, @minutes, @seconds = units
end

#eachObject

Convenient iterator for going through each duration unit from lowest to highest. (Goes from seconds…weeks)



97
98
99
# File 'lib/duration.rb', line 97

def each
  UNITS.each { |unit| yield unit, __send__(unit) }
end

#format(format_str) ⇒ Object Also known as: strftime

Format a duration into a human-readable string.

%w  => weeks
%d  => days
%h  => hours
%m  => minutes
%s  => seconds
%t  => total seconds
%H  => zero-padded hours
%M  => zero-padded minutes
%S  => zero-padded seconds
%~s => locale-dependent "seconds" terminology
%~m => locale-dependent "minutes" terminology
%~h => locale-dependent "hours" terminology
%~d => locale-dependent "days" terminology
%~w => locale-dependent "weeks" terminology


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/duration.rb', line 118

def format(format_str)
  identifiers = {
    'w'  => @weeks,
    'd'  => @days,
    'h'  => @hours,
    'm'  => @minutes,
    's'  => @seconds,
    't'  => @total,
    'H'  => @hours.to_s.rjust(2, '0'),
    'M'  => @minutes.to_s.rjust(2, '0'),
    'S'  => @seconds.to_s.rjust(2, '0'),
    '~s' => @seconds == 1 ? @@locale.singulars[0] : @@locale.plurals[0],
    '~m' => @minutes == 1 ? @@locale.singulars[1] : @@locale.plurals[1],
    '~h' => @hours   == 1 ? @@locale.singulars[2] : @@locale.plurals[2],
    '~d' => @days    == 1 ? @@locale.singulars[3] : @@locale.plurals[3],
    '~w' => @weeks   == 1 ? @@locale.singulars[4] : @@locale.plurals[4]
  }

format_str.gsub(/%?%(w|d|h|m|s|t|H|M|S|~(?:s|m|h|d|w))/) do |match|
	match['%%'] ? match : identifiers[match[1..-1]]
end.gsub('%%', '%')
end

#inspectObject

Inspect Duration object.



158
159
160
# File 'lib/duration.rb', line 158

def inspect
	"#<#{self.class}: #{(s = to_s).empty? ? '...' : s}>"
end

#to_sObject

String representation of the Duration object.



153
154
155
# File 'lib/duration.rb', line 153

def to_s
  @@locale.format.call(self)
end