business_time 0.9.1 → 0.11.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 +5 -5
- data/README.rdoc +8 -2
- data/lib/business_time/business_days.rb +27 -9
- data/lib/business_time/business_hours.rb +18 -4
- data/lib/business_time/config.rb +31 -26
- data/lib/business_time/time_extensions.rb +25 -0
- data/lib/business_time/version.rb +1 -1
- metadata +22 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e917428c31758c1ce02b1bfae4f1ab3c864e8b3eb3f12ec3556445c390506820
|
4
|
+
data.tar.gz: 1f8020bef45cdbdb1981fe9452633a427a202c7bc4d4f3390ca955b8f6c7a49c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ffe3ada04985e1f12d6eb8c011e6dcfd4c09f02dc589e82e73fac1571af3caad6c52c2e80d7e312eb05cbdf5eda1ce39a251e6df2378d389f9fc49884ab7a5c
|
7
|
+
data.tar.gz: 1c244d0e42b7222422e5b6d2317aa1bdf9f5339ee71cae551c7c9a406add3b84dc6eed57e8d58e19a21dce10af10ba96e521eeb124a327510ea1827a17d9e2c0
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= business_time
|
2
2
|
|
3
|
-
{<img src="https://
|
3
|
+
{<img src="https://github.com/bokmann/business_time/workflows/CI/badge.svg" />}[https://github.com/bokmann/business_time/actions?query=workflow%3ACI]
|
4
4
|
|
5
5
|
ActiveSupport gives us some great helpers so we can do things like:
|
6
6
|
|
@@ -61,6 +61,11 @@ We can adjust the start and end time of our business hours
|
|
61
61
|
BusinessTime::Config.beginning_of_workday = "8:30 am"
|
62
62
|
BusinessTime::Config.end_of_workday = "5:30 pm"
|
63
63
|
|
64
|
+
Or we can temporarily override the configured values
|
65
|
+
BusinessTime::Config.with(beginning_of_workday: "8 am", end_of_workday: "6 pm") do
|
66
|
+
1.business_hour.from_now
|
67
|
+
end
|
68
|
+
|
64
69
|
and we can add holidays that don't count as business days
|
65
70
|
July 5 in 2010 is a monday that the U.S. takes off because our independence day falls on that Sunday.
|
66
71
|
three_day_weekend = Date.parse("July 5th, 2010")
|
@@ -166,6 +171,7 @@ Timezone relative date handling gets more and more complicated every time you lo
|
|
166
171
|
|
167
172
|
== Contributors
|
168
173
|
* David Bock http://github.com/bokmann
|
174
|
+
* Ryan McGeary http://github.com/rmm5t
|
169
175
|
* Enrico Bianco http://github.com/enricob
|
170
176
|
* Arild Shirazi http://github.com/ashirazi
|
171
177
|
* Piotr Jakubowski http://github.com/piotrj
|
@@ -220,4 +226,4 @@ I'm proud of the work in this gem; the stability is a big part of that. This ge
|
|
220
226
|
|
221
227
|
== Copyright
|
222
228
|
|
223
|
-
Copyright (c) 2010-
|
229
|
+
Copyright (c) 2010-2021 bokmann. See LICENSE for details.
|
@@ -17,7 +17,29 @@ module BusinessTime
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def after(time = Time.current)
|
20
|
-
|
20
|
+
non_negative_days? ? calculate_after(time, @days) : calculate_before(time, -@days)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :from_now, :after
|
24
|
+
alias_method :since, :after
|
25
|
+
|
26
|
+
def before(time = Time.current)
|
27
|
+
non_negative_days? ? calculate_before(time, @days) : calculate_after(time, -@days)
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :ago, :before
|
31
|
+
alias_method :until, :before
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def non_negative_days?
|
36
|
+
@days >= 0
|
37
|
+
end
|
38
|
+
|
39
|
+
def calculate_after(time, days)
|
40
|
+
if (time.is_a?(Time) || time.is_a?(DateTime)) && !time.workday?
|
41
|
+
time = Time.beginning_of_workday(time)
|
42
|
+
end
|
21
43
|
while days > 0 || !time.workday?
|
22
44
|
days -= 1 if time.workday?
|
23
45
|
time += 1.day
|
@@ -30,11 +52,10 @@ module BusinessTime
|
|
30
52
|
time
|
31
53
|
end
|
32
54
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
days = @days
|
55
|
+
def calculate_before(time, days)
|
56
|
+
if (time.is_a?(Time) || time.is_a?(DateTime)) && !time.workday?
|
57
|
+
time = Time.beginning_of_workday(time)
|
58
|
+
end
|
38
59
|
while days > 0 || !time.workday?
|
39
60
|
days -= 1 if time.workday?
|
40
61
|
time -= 1.day
|
@@ -48,8 +69,5 @@ module BusinessTime
|
|
48
69
|
end
|
49
70
|
time
|
50
71
|
end
|
51
|
-
|
52
|
-
alias_method :ago, :before
|
53
|
-
alias_method :until, :before
|
54
72
|
end
|
55
73
|
end
|
@@ -24,9 +24,24 @@ module BusinessTime
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def after(time)
|
27
|
+
non_negative_hours? ? calculate_after(time, @hours) : calculate_before(time, -@hours)
|
28
|
+
end
|
29
|
+
alias_method :since, :after
|
30
|
+
|
31
|
+
def before(time)
|
32
|
+
non_negative_hours? ? calculate_before(time, @hours) : calculate_after(time, -@hours)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def non_negative_hours?
|
38
|
+
@hours >= 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def calculate_after(time, hours)
|
27
42
|
after_time = Time.roll_forward(time)
|
28
43
|
# Step through the hours, skipping over non-business hours
|
29
|
-
|
44
|
+
hours.times do
|
30
45
|
after_time = after_time + 1.hour
|
31
46
|
|
32
47
|
if after_time.hour == 0 && after_time.min == 0 && after_time.sec == 0
|
@@ -44,12 +59,11 @@ module BusinessTime
|
|
44
59
|
end
|
45
60
|
after_time
|
46
61
|
end
|
47
|
-
alias_method :since, :after
|
48
62
|
|
49
|
-
def
|
63
|
+
def calculate_before(time, hours)
|
50
64
|
before_time = Time.roll_backward(time)
|
51
65
|
# Step through the hours, skipping over non-business hours
|
52
|
-
|
66
|
+
hours.times do
|
53
67
|
before_time = before_time - 1.hour
|
54
68
|
|
55
69
|
if before_time.hour == 0 && before_time.min == 0 && before_time.sec == 0
|
data/lib/business_time/config.rb
CHANGED
@@ -47,15 +47,19 @@ module BusinessTime
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def local_config
|
50
|
-
|
50
|
+
local_config_stack.last
|
51
51
|
end
|
52
52
|
|
53
53
|
def local_config=(config)
|
54
|
-
|
54
|
+
local_config_stack.last.replace(config)
|
55
|
+
end
|
56
|
+
|
57
|
+
def local_config_stack
|
58
|
+
Thread.current[:business_time_local_config] ||= []
|
55
59
|
end
|
56
60
|
|
57
61
|
def local_config?
|
58
|
-
!
|
62
|
+
!local_config_stack.empty?
|
59
63
|
end
|
60
64
|
|
61
65
|
def threadsafe_cattr_accessor(name)
|
@@ -76,23 +80,7 @@ module BusinessTime
|
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
79
|
-
|
80
|
-
# by saying
|
81
|
-
# BusinessTime::Config.beginning_of_workday = "8:30 am"
|
82
|
-
# someplace in the initializers of your application.
|
83
|
-
threadsafe_cattr_reader :beginning_of_workday
|
84
|
-
|
85
|
-
# You can set this yourself, either by the load method below, or
|
86
|
-
# by saying
|
87
|
-
# BusinessTime::Config.end_of_workday = "5:30 pm"
|
88
|
-
# someplace in the initializers of your application.
|
89
|
-
threadsafe_cattr_reader :end_of_workday
|
90
|
-
|
91
|
-
# You can set this yourself, either by the load method below, or
|
92
|
-
# by saying
|
93
|
-
# BusinessTime::Config.work_week = [:sun, :mon, :tue, :wed, :thu]
|
94
|
-
# someplace in the initializers of your application.
|
95
|
-
threadsafe_cattr_accessor :work_week
|
83
|
+
threadsafe_cattr_reader :work_week
|
96
84
|
|
97
85
|
# You can set this yourself, either by the load method below, or
|
98
86
|
# by saying
|
@@ -114,6 +102,10 @@ module BusinessTime
|
|
114
102
|
threadsafe_cattr_accessor :fiscal_month_offset
|
115
103
|
|
116
104
|
class << self
|
105
|
+
# You can set this yourself, either by the load method below, or
|
106
|
+
# by saying
|
107
|
+
# BusinessTime::Config.end_of_workday = "5:30 pm"
|
108
|
+
# someplace in the initializers of your application.
|
117
109
|
def end_of_workday(day=nil)
|
118
110
|
if day
|
119
111
|
wday = work_hours[int_to_wday(day.wday)]
|
@@ -123,6 +115,10 @@ module BusinessTime
|
|
123
115
|
end
|
124
116
|
end
|
125
117
|
|
118
|
+
# You can set this yourself, either by the load method below, or
|
119
|
+
# by saying
|
120
|
+
# BusinessTime::Config.beginning_of_workday = "8:30 am"
|
121
|
+
# someplace in the initializers of your application.
|
126
122
|
def beginning_of_workday(day=nil)
|
127
123
|
if day
|
128
124
|
wday = work_hours[int_to_wday(day.wday)]
|
@@ -132,6 +128,10 @@ module BusinessTime
|
|
132
128
|
end
|
133
129
|
end
|
134
130
|
|
131
|
+
# You can set this yourself, either by the load method below, or
|
132
|
+
# by saying
|
133
|
+
# BusinessTime::Config.work_week = [:sun, :mon, :tue, :wed, :thu]
|
134
|
+
# someplace in the initializers of your application.
|
135
135
|
def work_week=(days)
|
136
136
|
config[:work_week] = days
|
137
137
|
self._weekdays = nil
|
@@ -173,11 +173,11 @@ module BusinessTime
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def with(config)
|
176
|
-
|
176
|
+
local_config_stack.push(config().dup)
|
177
177
|
config.each { |k,v| send("#{k}=", v) } # calculations are done on setting
|
178
178
|
yield
|
179
179
|
ensure
|
180
|
-
|
180
|
+
local_config_stack.pop
|
181
181
|
end
|
182
182
|
|
183
183
|
def default_config
|
@@ -186,18 +186,23 @@ module BusinessTime
|
|
186
186
|
|
187
187
|
private
|
188
188
|
|
189
|
+
DAY_NAMES = [
|
190
|
+
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'
|
191
|
+
]
|
192
|
+
private_constant :DAY_NAMES
|
193
|
+
|
189
194
|
def wday_to_int day_name
|
190
|
-
lowercase_day_names =
|
195
|
+
lowercase_day_names = DAY_NAMES.map(&:downcase)
|
191
196
|
lowercase_day_names.find_index(day_name.to_s.downcase)
|
192
197
|
end
|
193
198
|
|
194
199
|
def int_to_wday num
|
195
|
-
|
200
|
+
DAY_NAMES.map(&:downcase).map(&:to_sym)[num]
|
196
201
|
end
|
197
202
|
|
198
203
|
def reset
|
199
|
-
|
200
|
-
self.
|
204
|
+
local_config_stack.clear
|
205
|
+
self.config = default_config
|
201
206
|
end
|
202
207
|
|
203
208
|
def deep_dup(object)
|
@@ -169,5 +169,30 @@ module BusinessTime
|
|
169
169
|
def during_business_hours?
|
170
170
|
self.workday? && self.to_i.between?(Time.beginning_of_workday(self).to_i, Time.end_of_workday(self).to_i)
|
171
171
|
end
|
172
|
+
|
173
|
+
def consecutive_workdays
|
174
|
+
workday? ? consecutive_days { |date| date.workday? } : []
|
175
|
+
end
|
176
|
+
|
177
|
+
def consecutive_non_working_days
|
178
|
+
!workday? ? consecutive_days { |date| !date.workday? } : []
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
|
183
|
+
def consecutive_days
|
184
|
+
days = []
|
185
|
+
date = self + 1.day
|
186
|
+
while yield(date)
|
187
|
+
days << date
|
188
|
+
date += 1.day
|
189
|
+
end
|
190
|
+
date = self - 1.day
|
191
|
+
while yield(date)
|
192
|
+
days << date
|
193
|
+
date -= 1.day
|
194
|
+
end
|
195
|
+
(days << self).sort
|
196
|
+
end
|
172
197
|
end
|
173
198
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: business_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bokmann
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: tzinfo
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sorted_set
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,7 +136,7 @@ homepage: https://github.com/bokmann/business_time
|
|
122
136
|
licenses:
|
123
137
|
- MIT
|
124
138
|
metadata: {}
|
125
|
-
post_install_message:
|
139
|
+
post_install_message:
|
126
140
|
rdoc_options: []
|
127
141
|
require_paths:
|
128
142
|
- lib
|
@@ -137,9 +151,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '0'
|
139
153
|
requirements: []
|
140
|
-
|
141
|
-
|
142
|
-
signing_key:
|
154
|
+
rubygems_version: 3.2.31
|
155
|
+
signing_key:
|
143
156
|
specification_version: 4
|
144
157
|
summary: Support for doing time math in business hours and days
|
145
158
|
test_files: []
|