working_hours 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/CHANGELOG.md +5 -1
- data/README.md +2 -2
- data/lib/working_hours/computation.rb +8 -8
- data/lib/working_hours/config.rb +1 -2
- data/lib/working_hours/version.rb +1 -1
- data/spec/working_hours/computation_spec.rb +22 -0
- data/spec/working_hours/config_spec.rb +12 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bdb747e39a652368403adb9ad97f3776a8d8ab28f841d70912bcab6141118ea
|
4
|
+
data.tar.gz: 74e1447b590b829f95e52fe3c5bac18e7a690dcc8b21683402982f5810b94d8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee953af27c8d6622d8089feec9cd5b966613baff8239c11e488668ad07a48023efbd98d28599f9723c913b7e295ced2ac2b4cb5ef70711c4950ed8afea2aa107
|
7
|
+
data.tar.gz: 5b632e842d20ff83173c83a3e34c4bf166237f3689ba130db2cfd3031e027078f1efa1acbddac588198d78b07f3775c94e88f6d83fba328a9400629e92fab107
|
data/.travis.yml
CHANGED
@@ -4,7 +4,8 @@ rvm:
|
|
4
4
|
- 2.5.7
|
5
5
|
- 2.6.5
|
6
6
|
- 2.7.0
|
7
|
-
-
|
7
|
+
- 3.0.0
|
8
|
+
- jruby-9.2.14.0
|
8
9
|
gemfile:
|
9
10
|
- gemfiles/Gemfile.activesupport-4.x
|
10
11
|
- gemfiles/Gemfile.activesupport-5.x
|
@@ -15,6 +16,8 @@ jobs:
|
|
15
16
|
gemfile: gemfiles/Gemfile.activesupport-6.x
|
16
17
|
- rvm: 2.7.0
|
17
18
|
gemfile: gemfiles/Gemfile.activesupport-4.x
|
19
|
+
- rvm: 3.0.0
|
20
|
+
gemfile: gemfiles/Gemfile.activesupport-4.x
|
18
21
|
include:
|
19
22
|
- rvm: ruby-head
|
20
23
|
gemfile: gemfiles/Gemfile.activesupport-edge
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
-
[Compare master with v1.
|
3
|
+
[Compare master with v1.3.0](https://github.com/intrepidd/working_hours/compare/v1.3.0...master)
|
4
|
+
|
5
|
+
# v1.3.0
|
6
|
+
* Improve supports for fractional seconds in input times by only rounding results at the end - [#42](https://github.com/Intrepidd/working_hours/issues/42) [#43](https://github.com/Intrepidd/working_hours/pull/43)
|
7
|
+
* Increase code safety by always initializing an empty hash for each day of the week in the precompiled config (inspired by [#35](https://github.com/Intrepidd/working_hours/pull/35)
|
4
8
|
|
5
9
|
# v1.2.0
|
6
10
|
* Drop support for ruby 2.0, 2.1, 2.2 and 2.3
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# WorkingHours
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.
|
3
|
+
[![Build Status](https://travis-ci.com/Intrepidd/working_hours.svg?branch=master)](https://travis-ci.com/Intrepidd/working_hours)
|
4
4
|
|
5
5
|
A modern ruby gem allowing to do time calculation with working hours.
|
6
6
|
|
7
7
|
Compatible and tested with:
|
8
|
-
- Ruby `2.4`, `2.5`, `2.6`, `2.7`, JRuby `9.2`
|
8
|
+
- Ruby `2.4`, `2.5`, `2.6`, `2.7`, `3.0`, JRuby `9.2`
|
9
9
|
- ActiveSupport `4.x`, `5.x`, `6.x`
|
10
10
|
|
11
11
|
## Installation
|
@@ -34,7 +34,7 @@ module WorkingHours
|
|
34
34
|
|
35
35
|
def add_seconds origin, seconds, config: nil
|
36
36
|
config ||= wh_config
|
37
|
-
time = in_config_zone(origin, config: config)
|
37
|
+
time = in_config_zone(origin, config: config)
|
38
38
|
while seconds > 0
|
39
39
|
# roll to next business period
|
40
40
|
time = advance_to_working_time(time, config: config)
|
@@ -72,7 +72,7 @@ module WorkingHours
|
|
72
72
|
|
73
73
|
def advance_to_working_time time, config: nil
|
74
74
|
config ||= wh_config
|
75
|
-
time = in_config_zone(time, config: config)
|
75
|
+
time = in_config_zone(time, config: config)
|
76
76
|
loop do
|
77
77
|
# skip holidays and weekends
|
78
78
|
while not working_day?(time, config: config)
|
@@ -80,7 +80,7 @@ module WorkingHours
|
|
80
80
|
end
|
81
81
|
# find first working range after time
|
82
82
|
time_in_day = time.seconds_since_midnight
|
83
|
-
|
83
|
+
config[:working_hours][time.wday].each do |from, to|
|
84
84
|
return time if time_in_day >= from and time_in_day < to
|
85
85
|
return time + (from - time_in_day) if from >= time_in_day
|
86
86
|
end
|
@@ -91,7 +91,7 @@ module WorkingHours
|
|
91
91
|
|
92
92
|
def advance_to_closing_time time, config: nil
|
93
93
|
config ||= wh_config
|
94
|
-
time = in_config_zone(time, config: config)
|
94
|
+
time = in_config_zone(time, config: config)
|
95
95
|
loop do
|
96
96
|
# skip holidays and weekends
|
97
97
|
while not working_day?(time, config: config)
|
@@ -100,7 +100,7 @@ module WorkingHours
|
|
100
100
|
# find next working range after time
|
101
101
|
time_in_day = time.seconds_since_midnight
|
102
102
|
time = time.beginning_of_day
|
103
|
-
|
103
|
+
config[:working_hours][time.wday].each do |from, to|
|
104
104
|
return time + to if time_in_day >= from and time_in_day < to
|
105
105
|
return time + to if from >= time_in_day
|
106
106
|
end
|
@@ -123,7 +123,7 @@ module WorkingHours
|
|
123
123
|
|
124
124
|
def return_to_exact_working_time time, config: nil
|
125
125
|
config ||= wh_config
|
126
|
-
time = in_config_zone(time, config: config)
|
126
|
+
time = in_config_zone(time, config: config)
|
127
127
|
loop do
|
128
128
|
# skip holidays and weekends
|
129
129
|
while not working_day?(time, config: config)
|
@@ -131,7 +131,7 @@ module WorkingHours
|
|
131
131
|
end
|
132
132
|
# find last working range before time
|
133
133
|
time_in_day = time.seconds_since_midnight
|
134
|
-
|
134
|
+
config[:working_hours][time.wday].reverse_each do |from, to|
|
135
135
|
# round is used to suppress miliseconds hack from `end_of_day`
|
136
136
|
return time if time_in_day > from and time_in_day <= to
|
137
137
|
return (time - (time_in_day - to)) if to <= time_in_day
|
@@ -180,7 +180,7 @@ module WorkingHours
|
|
180
180
|
-working_time_between(to, from, config: config)
|
181
181
|
else
|
182
182
|
from = advance_to_working_time(in_config_zone(from, config: config))
|
183
|
-
to = in_config_zone(to, config: config)
|
183
|
+
to = in_config_zone(to, config: config)
|
184
184
|
distance = 0
|
185
185
|
while from < to
|
186
186
|
# look at working ranges
|
data/lib/working_hours/config.rb
CHANGED
@@ -44,9 +44,8 @@ module WorkingHours
|
|
44
44
|
validate_working_hours! config[:working_hours]
|
45
45
|
validate_holidays! config[:holidays]
|
46
46
|
validate_time_zone! config[:time_zone]
|
47
|
-
compiled = {working_hours:
|
47
|
+
compiled = { working_hours: Array.new(7) { Hash.new } }
|
48
48
|
working_hours.each do |day, hours|
|
49
|
-
compiled[:working_hours][DAYS_OF_WEEK.index(day)] = {}
|
50
49
|
hours.each do |start, finish|
|
51
50
|
compiled[:working_hours][DAYS_OF_WEEK.index(day)][compile_time(start)] = compile_time(finish)
|
52
51
|
end
|
@@ -129,6 +129,13 @@ describe WorkingHours::Computation do
|
|
129
129
|
time = Time.utc(2014, 4, 8, 0, 0, 30) # Tuesday
|
130
130
|
expect(add_seconds(time, -60)).to eq(Time.utc(2014, 4, 7, 23, 59, 00))
|
131
131
|
end
|
132
|
+
|
133
|
+
it 'honors miliseconds in the base time and increment (but return rounded result)' do
|
134
|
+
# Rounding the base time or increments before the end would yield a wrong result
|
135
|
+
time = Time.utc(1991, 11, 15, 16, 59, 42.25) # +250ms
|
136
|
+
expect(add_seconds(time, 120.4)).to eq(Time.utc(1991, 11, 18, 9, 1, 43))
|
137
|
+
end
|
138
|
+
|
132
139
|
end
|
133
140
|
|
134
141
|
describe '#advance_to_working_time' do
|
@@ -536,5 +543,20 @@ describe WorkingHours::Computation do
|
|
536
543
|
Time.new(2014, 4, 7, 15, 0, 0, "-04:00"), # Monday 7pm in UTC
|
537
544
|
)).to eq(7.hours)
|
538
545
|
end
|
546
|
+
|
547
|
+
# generates two times with +0ms, +250ms, +500ms, +750ms and +1s
|
548
|
+
# then for each combination compare the result with a ruby diff
|
549
|
+
context 'with precise miliseconds timings' do
|
550
|
+
reference = Time.utc(2014, 4, 7, 10)
|
551
|
+
0.step(1.0, 0.25) do |offset1|
|
552
|
+
0.step(1.0, 0.25) do |offset2|
|
553
|
+
from = reference + offset1
|
554
|
+
to = reference + offset2
|
555
|
+
it "returns expected value (#{(to - from).round}) for #{offset1} — #{offset2} interval" do
|
556
|
+
expect(working_time_between(from, to)).to eq((to - from).round)
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
560
|
+
end
|
539
561
|
end
|
540
562
|
end
|
@@ -266,16 +266,23 @@ describe WorkingHours::Config do
|
|
266
266
|
|
267
267
|
it 'computes an optimized version' do
|
268
268
|
expect(subject).to eq({
|
269
|
-
:working_hours => [
|
269
|
+
:working_hours => [{}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {}],
|
270
270
|
:holidays => Set.new([]),
|
271
271
|
:time_zone => ActiveSupport::TimeZone['UTC']
|
272
272
|
})
|
273
273
|
end
|
274
274
|
|
275
|
+
it 'includes default values for each days so computation does not fail' do
|
276
|
+
WorkingHours::Config.working_hours = {:mon => {'08:00' => '14:00'}}
|
277
|
+
expect(subject[:working_hours]).to eq([{}, {28800=>50400}, {}, {}, {}, {}, {}])
|
278
|
+
expect(WorkingHours.working_time_between(Time.utc(2014, 4, 14, 0), Time.utc(2014, 4, 21, 0))).to eq(3600*6)
|
279
|
+
expect(WorkingHours.add_seconds(Time.utc(2014, 4, 14, 0), 3600*7)).to eq(Time.utc(2014, 4, 21, 9))
|
280
|
+
end
|
281
|
+
|
275
282
|
it 'supports seconds' do
|
276
283
|
WorkingHours::Config.working_hours = {:mon => {'20:32:59' => '22:59:59'}}
|
277
284
|
expect(subject).to eq({
|
278
|
-
:working_hours => [
|
285
|
+
:working_hours => [{}, {73979 => 82799}, {}, {}, {}, {}, {}],
|
279
286
|
:holidays => Set.new([]),
|
280
287
|
:time_zone => ActiveSupport::TimeZone['UTC']
|
281
288
|
})
|
@@ -284,7 +291,7 @@ describe WorkingHours::Config do
|
|
284
291
|
it 'supports 24:00 (converts to 23:59:59.999999)' do
|
285
292
|
WorkingHours::Config.working_hours = {:mon => {'20:00' => '24:00'}}
|
286
293
|
expect(subject).to eq({
|
287
|
-
:working_hours => [
|
294
|
+
:working_hours => [{}, {72000 => 86399.999999}, {}, {}, {}, {}, {}],
|
288
295
|
:holidays => Set.new([]),
|
289
296
|
:time_zone => ActiveSupport::TimeZone['UTC']
|
290
297
|
})
|
@@ -296,9 +303,9 @@ describe WorkingHours::Config do
|
|
296
303
|
}.to change {
|
297
304
|
WorkingHours::Config.precompiled[:working_hours]
|
298
305
|
}.from(
|
299
|
-
[
|
306
|
+
[{}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {}]
|
300
307
|
).to(
|
301
|
-
[
|
308
|
+
[{}, {28800=>50400}, {}, {}, {}, {}, {}]
|
302
309
|
)
|
303
310
|
end
|
304
311
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: working_hours
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrien Jarthon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -152,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
requirements: []
|
155
|
-
rubygems_version: 3.0.
|
155
|
+
rubygems_version: 3.0.3
|
156
156
|
signing_key:
|
157
157
|
specification_version: 4
|
158
158
|
summary: time calculation with working hours
|