Class: Smalltime::Duration

Inherits:
Object
  • Object
show all
Defined in:
lib/smalltime.rb

Overview

Duration represents a segment of time.

Instance Method Summary collapse

Constructor Details

#initialize(millenia: 0, centuries: 0, decades: 0, years: 0, months: 0, weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0, deciseconds: 0, centiseconds: 0, milliseconds: 0, microseconds: 0, nanoseconds: 0, picoseconds: 0, femtoseconds: 0, attoseconds: 0, zeptoseconds: 0, yoctoseconds: 0) ⇒ Duration

Create a new smalltime. A smalltime is an arbitrarily precise duration immune to floating point errors and having advanced formatting capabilities.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/smalltime.rb', line 145

def initialize(
  millenia: 0,
  centuries: 0,
  decades: 0,
  years: 0,
  months: 0,
  weeks: 0,
  days: 0,
  hours: 0,
  minutes: 0,
  seconds: 0,
  deciseconds: 0,
  centiseconds: 0,
  milliseconds: 0,
  microseconds: 0,
  nanoseconds: 0,
  picoseconds: 0,
  femtoseconds: 0,
  attoseconds: 0,
  zeptoseconds: 0,
  yoctoseconds: 0
)
  @parts = {
    yoctoseconds: yoctoseconds,
    zeptoseconds: zeptoseconds,
    attoseconds: attoseconds,
    femtoseconds: femtoseconds,
    picoseconds: picoseconds,
    nanoseconds: nanoseconds,
    microseconds: microseconds,
    milliseconds: milliseconds,
    centiseconds: centiseconds,
    deciseconds: deciseconds,
    seconds: seconds,
    minutes: minutes,
    hours: hours,
    days: days,
    weeks: weeks,
    months: months,
    years: years,
    decades: decades,
    centuries: centuries,
    millenia: millenia
  }

  Smalltime.units[0..-2].each.with_index do |unit, i|
    next unless @parts.key?(unit.plural)

    div, mod = @parts[unit.plural].divmod(Smalltime.units[i + 1].multiplier)
    @parts[unit.plural] = mod
    @parts[Smalltime.units[i + 1].plural] += div
  end
end

Instance Method Details

#attosecondsObject



267
268
269
# File 'lib/smalltime.rb', line 267

def attoseconds
  @parts[:attoseconds]
end

#bigger_part(part, by: 1) ⇒ Object

Given a part key like :seconds, returns the next-biggest part key like :minutes. If ‘by` is given, instead returns the part `by` levels bigger. For example, `bigger_part(:seconds, by: 2)` returns `:hours`.



282
283
284
# File 'lib/smalltime.rb', line 282

def bigger_part(part, by: 1)
  @parts.keys[@parts.keys.find_index(part) + by]
end

#biggest_nonzero_unitObject



351
352
353
354
355
356
357
# File 'lib/smalltime.rb', line 351

def biggest_nonzero_unit
  @parts.to_a.reverse.to_h.find do |unit, val|
    if val != 0
      return unit
    end
  end
end

#build(seconds) ⇒ Smalltime

Create a new Smalltime::Duration out of seconds. This method is provided as a drop-in replacement for ActiveSupport::Duration.build.

Parameters:

  • seconds (Fixnum)

    the number of total seconds in the duration

Returns:



307
308
309
# File 'lib/smalltime.rb', line 307

def build(seconds)
  new(seconds: seconds)
end

#casual(units: 1) ⇒ Object

Return a duration imprecisely formatted like “123s” or “4mo 3d”. The number of units displayed is ‘units`, with the largest nonzero unit being the first and the remaining ones sequentially getting more precise (e.g. “3mo 21d”, “4h 0m”).

If the duration is exactly 0, “-” is returned.



338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/smalltime.rb', line 338

def casual(units: 1)
  string_components = []

  units.times do |unit_offset|
    return "-" if biggest_nonzero_unit.nil?
    u = Smalltime.unit_by_name(smaller_part(biggest_nonzero_unit, by: unit_offset))
    string_components << "#{@parts[u.pluralize.to_sym]}#{u.shortname}"
  end

  return "-" if string_components.empty?
  string_components.join(" ")
end

#centisecondsObject



243
244
245
# File 'lib/smalltime.rb', line 243

def centiseconds
  @parts[:centiseconds]
end

#centuriesObject



203
204
205
# File 'lib/smalltime.rb', line 203

def centuries
  @parts[:centuries]
end

#clocklike(precise: false, sign: :negative) ⇒ Object

Return a duration formatted like “HH:MM:SS”. If precise is true, it returns a time like “HH:MM:SS.cc” instead.

When sign is :always, the returned value always has a “+” or “-” in front of it. When sign is :never, the returned value never has a sign in front of it. When sign is :negative, only negative values have a sign (default).



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/smalltime.rb', line 317

def clocklike(precise: false, sign: :negative)
  format = ["%02d", ":%02d", ":%02d"]
  components = [hours, minutes, seconds]

  if precise
    format << ".%02d"
    components << (milliseconds / 10)
  end

  if sign == :always || (sign == :negative && negative?)
    format[0] = "%0+2d"
  end

  Kernel.format(format.join, *components)
end

#daysObject



223
224
225
# File 'lib/smalltime.rb', line 223

def days
  @parts[:days]
end

#decadesObject



207
208
209
# File 'lib/smalltime.rb', line 207

def decades
  @parts[:decades]
end

#decisecondsObject



239
240
241
# File 'lib/smalltime.rb', line 239

def deciseconds
  @parts[:deciseconds]
end

#femtosecondsObject



263
264
265
# File 'lib/smalltime.rb', line 263

def femtoseconds
  @parts[:femtoseconds]
end

#hoursObject



227
228
229
# File 'lib/smalltime.rb', line 227

def hours
  @parts[:hours]
end

#microsecondsObject



251
252
253
# File 'lib/smalltime.rb', line 251

def microseconds
  @parts[:microseconds]
end

#milleniaObject



199
200
201
# File 'lib/smalltime.rb', line 199

def millenia
  @parts[:millenia]
end

#millisecondsObject



247
248
249
# File 'lib/smalltime.rb', line 247

def milliseconds
  @parts[:milliseconds]
end

#minutesObject



231
232
233
# File 'lib/smalltime.rb', line 231

def minutes
  @parts[:minutes]
end

#monthsObject



215
216
217
# File 'lib/smalltime.rb', line 215

def months
  @parts[:months]
end

#nanosecondsObject



255
256
257
# File 'lib/smalltime.rb', line 255

def nanoseconds
  @parts[:nanoseconds]
end

#picosecondsObject



259
260
261
# File 'lib/smalltime.rb', line 259

def picoseconds
  @parts[:picoseconds]
end

#precisionObject



293
294
295
296
297
# File 'lib/smalltime.rb', line 293

def precision
  @parts.each do |unit, value|
    return unit if value != 0
  end
end

#secondsObject



235
236
237
# File 'lib/smalltime.rb', line 235

def seconds
  @parts[:seconds]
end

#smaller_part(part, by: 1) ⇒ Object

Given a part key like :minutes, returns the next-smallest part key like :seconds. If ‘by` is given, instead returns the part `by` levels smaller. For example, `smaller_part(:hours, by: 2)` returns `:seconds`.



289
290
291
# File 'lib/smalltime.rb', line 289

def smaller_part(part, by: 1)
  @parts.keys[@parts.keys.find_index(part) - by]
end

#to_sObject



299
300
# File 'lib/smalltime.rb', line 299

def to_s
end

#weeksObject



219
220
221
# File 'lib/smalltime.rb', line 219

def weeks
  @parts[:weeks]
end

#yearsObject



211
212
213
# File 'lib/smalltime.rb', line 211

def years
  @parts[:years]
end

#yoctosecondsObject



275
276
277
# File 'lib/smalltime.rb', line 275

def yoctoseconds
  @parts[:yoctoseconds]
end

#zeptosecondsObject



271
272
273
# File 'lib/smalltime.rb', line 271

def zeptoseconds
  @parts[:zeptoseconds]
end