timerizer 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|