working_hours 1.2.0 → 1.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c6ba325dcb5811a04a8eb5102e65b6d48e291a7d4a581baaf6f5e63b5394cf1
4
- data.tar.gz: 302e9f7a199ac7db4049e288f141c7dad3674e6618f99a2c4380af14e316b121
3
+ metadata.gz: 4bdb747e39a652368403adb9ad97f3776a8d8ab28f841d70912bcab6141118ea
4
+ data.tar.gz: 74e1447b590b829f95e52fe3c5bac18e7a690dcc8b21683402982f5810b94d8c
5
5
  SHA512:
6
- metadata.gz: d5ff45d737ba62afd04c0322d4010e6bac9cad0954a1fadcbd38564540367f32e2e8da8f78529921f755a46663cd1dbabf4562ec6d02235d8c1d0ddcc047316b
7
- data.tar.gz: 686a39afbad5ff340de57db83173dd75dd6c2b5b0ec244e25fbc2263b2eb7f90764f7cb8a95aed53a689507c19b4ba337a987ee00eac33bdce0c9fc903865772
6
+ metadata.gz: ee953af27c8d6622d8089feec9cd5b966613baff8239c11e488668ad07a48023efbd98d28599f9723c913b7e295ced2ac2b4cb5ef70711c4950ed8afea2aa107
7
+ data.tar.gz: 5b632e842d20ff83173c83a3e34c4bf166237f3689ba130db2cfd3031e027078f1efa1acbddac588198d78b07f3775c94e88f6d83fba328a9400629e92fab107
@@ -4,7 +4,8 @@ rvm:
4
4
  - 2.5.7
5
5
  - 2.6.5
6
6
  - 2.7.0
7
- - jruby-9.2.11.0
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
@@ -1,6 +1,10 @@
1
1
  # Unreleased
2
2
 
3
- [Compare master with v1.2.0](https://github.com/intrepidd/working_hours/compare/v1.2.0...master)
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.org/Intrepidd/working_hours.svg?branch=master)](https://travis-ci.org/Intrepidd/working_hours)
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).round
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).round
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
- (config[:working_hours][time.wday] || {}).each do |from, to|
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).round
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
- (config[:working_hours][time.wday] || {}).each do |from, to|
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).round
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
- (config[:working_hours][time.wday] || {}).reverse_each do |from, to|
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).round
183
+ to = in_config_zone(to, config: config)
184
184
  distance = 0
185
185
  while from < to
186
186
  # look at working ranges
@@ -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
@@ -1,3 +1,3 @@
1
1
  module WorkingHours
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  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 => [nil, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}],
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 => [nil, {73979 => 82799}],
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 => [nil, {72000 => 86399.999999}],
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
- [nil, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}]
306
+ [{}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {32400=>61200}, {}]
300
307
  ).to(
301
- [nil, {28800=>50400}]
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.2.0
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: 2020-04-15 00:00:00.000000000 Z
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.8
155
+ rubygems_version: 3.0.3
156
156
  signing_key:
157
157
  specification_version: 4
158
158
  summary: time calculation with working hours