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 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