timerizer 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/timerizer/duration/rounded_time.rb +163 -0
- data/lib/timerizer/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02461e09b8beea13b38f2e36aab85ab643fe7975b2f96132aa7bdbe8930ed370
|
4
|
+
data.tar.gz: 9fe1a1573e379256bedf1628ea469ec65c0e68f3a8da842ed77d995b0b70f753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1135496242298cd85e09d05d945b156cd592f76f9645a4b4bd3693e8cda1f3b190e8a27130a64337077ae62ab4b47f3205e8fbdeb6178034e358bb7f682dcbc6
|
7
|
+
data.tar.gz: baa46d6fe2ad8cec7bd48199081624dd31f2499235c04f319c0bd27b58417dfbc649f1e41cf207b2156985f56ca6a76148926cbc09ea083e2023dd3963bc2354
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Timerizer
|
5
|
+
class Duration
|
6
|
+
# Wraps rounding a {Timerizer::Duration} to the nearest value by the number
|
7
|
+
# of "places", which are customary time units (seconds, minutes, hours,
|
8
|
+
# days, months, years, etc; decades and weeks are not included).
|
9
|
+
#
|
10
|
+
# @private
|
11
|
+
class RoundedTime
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
# @!method remainder_times
|
15
|
+
# @return (see TermTimes#remainder_times)
|
16
|
+
# @!method target_unit
|
17
|
+
# @return (see TermTimes#target_unit)
|
18
|
+
# @!method times
|
19
|
+
# @return (see TermTimes#times)
|
20
|
+
def_delegators :@tt, :remainder_times, :target_unit, :times
|
21
|
+
|
22
|
+
# Default "places" (units, e.g., hours/minutes) to use for rounding.
|
23
|
+
DEFAULT_PLACES = 2
|
24
|
+
# Default {Timerizer::Duration::UNITS} *not* to include in rounded value.
|
25
|
+
OMITTED_KEYS = [:decades, :weeks]
|
26
|
+
|
27
|
+
# Given an original {Timerizer::Duration} instance, return a new instance
|
28
|
+
# that "rounds" the duration to the closest value expressed in a certain
|
29
|
+
# number of units (default 2).
|
30
|
+
#
|
31
|
+
# @param [{Timerizer::Duration}] duration Object encapsulating a duration
|
32
|
+
# (in hours, minutes, etc) to "round" to a number of
|
33
|
+
# units specified by `places`.
|
34
|
+
# @param [Integer] places Number of units to include in rounded value.
|
35
|
+
# Default is 2.
|
36
|
+
# @param [Array<Symbol>] omitted_keys Units to omit from calculation or
|
37
|
+
# return value. Default is `[:decades, :weeks]`
|
38
|
+
# @return {Timerizer::Duration}
|
39
|
+
# @example
|
40
|
+
# t = (12.hours 16.minutes 47.seconds).ago
|
41
|
+
# d = Time.since(t)
|
42
|
+
# d2 = RoundedTime.call(d)
|
43
|
+
# d.to_s # => "12 hours, 16 minutes, 47 seconds"
|
44
|
+
# d2.to_s # => "12 hours, 17 minutes"
|
45
|
+
#
|
46
|
+
def self.call(duration, places = DEFAULT_PLACES,
|
47
|
+
omitted_keys = OMITTED_KEYS)
|
48
|
+
new(duration, places, omitted_keys).call
|
49
|
+
end
|
50
|
+
|
51
|
+
# High-level method to do calculations on component durations.
|
52
|
+
#
|
53
|
+
# @return {Timerizer::Duration}
|
54
|
+
#
|
55
|
+
def call
|
56
|
+
remainder = sum_of(remainder_times)
|
57
|
+
sum_of(times) + offset_from(remainder)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Initial value for adding a collection of Duration instances.
|
63
|
+
# (see #sum_of)
|
64
|
+
ZERO_TIME = Timerizer::Duration.new(seconds: 0)
|
65
|
+
private_constant :ZERO_TIME
|
66
|
+
|
67
|
+
# Private initialiser to prevent direct instantiation by client code.
|
68
|
+
#
|
69
|
+
# @param [{Timerizer::Duration}] duration Object encapsulating a duration
|
70
|
+
# (in hours, minutes, etc) to "round" to a number of
|
71
|
+
# units specified by `places`.
|
72
|
+
# @param [Integer] places Number of units to include in rounded value.
|
73
|
+
# Default is 2.
|
74
|
+
# @param [Array<Symbol>] omitted_keys Units to omit from calculation or
|
75
|
+
# return value. Default is `[:decades, :weeks]`
|
76
|
+
#
|
77
|
+
def initialize(duration, places = DEFAULT_PLACES,
|
78
|
+
omitted_keys = OMITTED_KEYS)
|
79
|
+
@tt = TermTimes.new(duration, omitted_keys).call(places).freeze
|
80
|
+
end
|
81
|
+
|
82
|
+
# Determine whether returned {Timerizer::Duration} value should be rounded
|
83
|
+
# up or down based on a remainder value.
|
84
|
+
#
|
85
|
+
# If the remainder value is more than half of the {#target_unit}, then
|
86
|
+
# this will return a duration of 1 times the target unit, else a duration
|
87
|
+
# of {ZERO_TIME}.
|
88
|
+
#
|
89
|
+
# @return [{Timerizer::Duration}] Either zero or 1 times the `target_unit`
|
90
|
+
# @param [{Timerizer::Duration}] remainder Value of input duration less
|
91
|
+
# than one `target_unit`
|
92
|
+
def offset_from(remainder)
|
93
|
+
Timerizer::Duration.new((remainder * 2).to_units(target_unit))
|
94
|
+
end
|
95
|
+
|
96
|
+
# Add all time (Duration) values in an Array (or other Enumerable).
|
97
|
+
#
|
98
|
+
# @return [{Timerizer::Duration}] Sum total of input values.
|
99
|
+
# @param [Array<{Timerizer::Duration}>] Unit values to add together
|
100
|
+
#
|
101
|
+
def sum_of(time_values)
|
102
|
+
time_values.inject(ZERO_TIME, :+)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Convert a single {Timerizer::Duration} instance into an enumeration of
|
106
|
+
# per-unit Duration instances (hours, minutes, etc).
|
107
|
+
#
|
108
|
+
# @private
|
109
|
+
class TermTimes
|
110
|
+
# Least-significant time unit (e.g., ``:days`) used for rounding.
|
111
|
+
# @return [Symbol] Least-significant time unit in the resulting value.
|
112
|
+
attr_reader :target_unit
|
113
|
+
# Time units to be included in "rounded" result, before rounding.
|
114
|
+
# @return [Array<{Timerizer::Duration}>] Base result time-unit values.
|
115
|
+
attr_reader :times
|
116
|
+
# Time units to be "rounded" to adjust resulting Duration value.
|
117
|
+
# @return [Array<{Timerizer::Duration}>] Remaining time-unit values.
|
118
|
+
attr_reader :remainder_times
|
119
|
+
|
120
|
+
# Build array of time-part values based on input {Timerizer::Duration}.
|
121
|
+
#
|
122
|
+
# @param [{Timerizer::Duration}] duration Time differential used as
|
123
|
+
# input.
|
124
|
+
# @param [Array<Symbol>] omitted_keys {Timerizer::Duration::UNITS}
|
125
|
+
# values to exclude from resulting value.
|
126
|
+
#
|
127
|
+
def initialize(duration, omitted_keys)
|
128
|
+
@part_values = filter_units(duration, omitted_keys)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Compute per-unit {Timerizer::Duration} values, split based on unit
|
132
|
+
# count
|
133
|
+
#
|
134
|
+
# @param [Integer] places Number of time units to include in main Array.
|
135
|
+
def call(places)
|
136
|
+
# Note that `places` may exceed the number of actual units in the
|
137
|
+
# value. For example, with a duration of `(10.days)` and a `places`
|
138
|
+
# value of 2. Adjust as needed.
|
139
|
+
places = @part_values.count - 1 if @part_values.count < places
|
140
|
+
# If a zero-time `duration` is passed in, then @part_values will be
|
141
|
+
# empty, and the key arithmetic will return `nil`. Adjust as needed.
|
142
|
+
@target_unit = @part_values.keys[places - 1] || :seconds
|
143
|
+
term_times = unit_times
|
144
|
+
@times = term_times[0..places - 1]
|
145
|
+
@remainder_times = term_times[@times.count..-1]
|
146
|
+
self
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def filter_units(duration, omitted_keys)
|
152
|
+
unit_keys = Timerizer::Duration::UNITS.keys - omitted_keys
|
153
|
+
duration.to_units(*unit_keys).reject { |_, v| v.zero? }
|
154
|
+
end
|
155
|
+
|
156
|
+
def unit_times
|
157
|
+
@part_values.map { |unit, val| Timerizer::Duration.new(unit => val) }
|
158
|
+
end
|
159
|
+
end # class RoundedTime::TermTimes
|
160
|
+
private_constant :TermTimes
|
161
|
+
end # class RoundedTime
|
162
|
+
end
|
163
|
+
end
|
data/lib/timerizer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timerizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Lacy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/timerizer.rb
|
77
77
|
- lib/timerizer/core.rb
|
78
78
|
- lib/timerizer/duration.rb
|
79
|
+
- lib/timerizer/duration/rounded_time.rb
|
79
80
|
- lib/timerizer/version.rb
|
80
81
|
- lib/timerizer/wall_clock.rb
|
81
82
|
homepage: http://github.com/kylewlacy/timerizer
|