business 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +22 -0
- data/README.md +94 -7
- data/business.gemspec +3 -2
- data/lib/business/calendar.rb +12 -12
- data/lib/business/data/bacs.yml +1 -1
- data/lib/business/data/sepa.yml +1 -1
- data/lib/business/data/weekdays.yml +1 -1
- data/lib/business/version.rb +1 -1
- data/spec/calendar_spec.rb +60 -60
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba9a77c99ec8b8d8d62ce8dd67e03cfbcadf3948
|
4
|
+
data.tar.gz: 0e9f3652c8bf6a17ec0200786a0fff9bb99f2a2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c331e4584c468ff1760ef2d5e355355999eba3d5dbda0ce4ce172072be71e28b7dc98a279163b6b25c47b5aee4fc50a0ef3fabb6cbc47ccfc3b3442fdd7a8685
|
7
|
+
data.tar.gz: 625fd8b80ae09a43a4196477560997299f440fa3ddd1f2f6c77ee044c97ea472c8e8dfddba4ecee5ae8e0cea75aaa7f18d025ec51193f9946280f4879c41c3c5
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 GoCardless
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,13 +1,100 @@
|
|
1
|
-
#
|
1
|
+
# Business
|
2
2
|
|
3
|
-
Date calculations based on
|
3
|
+
Date calculations based on business calendars.
|
4
4
|
|
5
|
-
|
5
|
+
|
6
|
+
## But other libraries already do this
|
7
|
+
|
8
|
+
Another gem, business_time, also exists for this purpose. We previously used
|
9
|
+
business_time, but encountered several issues that prompted us to create
|
10
|
+
business.
|
11
|
+
|
12
|
+
Firstly, business_time works by monkey-patching `Date`, `Time`, and `FixNum`.
|
13
|
+
While this enables syntax like `Time.now + 1.business_day`, it means that all
|
14
|
+
configuration has to be global. GoCardless handles payments across multiple
|
15
|
+
geographies, so being able to work with multiple working-day calendars is
|
16
|
+
essential for us. Business provides a simple `Calendar` class, that is
|
17
|
+
initialized with a configuration that specifies which days of the week are
|
18
|
+
considered to be working days, and which dates are holidays.
|
19
|
+
|
20
|
+
Secondly, business_time supports calculations on times as well as dates. For
|
21
|
+
our purposes, date-based calculations are sufficient. Supporting time-based
|
22
|
+
calculations as well makes the code significantly more complex. We chose to
|
23
|
+
avoid this extra complexity by sticking solely to date-based mathematics.
|
24
|
+
|
25
|
+
|
26
|
+
## Documentation
|
27
|
+
|
28
|
+
### Getting started
|
29
|
+
|
30
|
+
Get stareted with business by creating an instance of the calendar class,
|
31
|
+
passing in a hash that specifies with days of the week are considered working
|
32
|
+
days, and which days are holidays.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
calendar = Business::Calendar.new(
|
36
|
+
working_days: %w( mon tue wed thu fri ),
|
37
|
+
holidays: ["01/01/2014", "03/01/2014"]
|
38
|
+
)
|
39
|
+
```
|
40
|
+
|
41
|
+
A few calendar configs are bundled with the gem. Load them by calling the
|
42
|
+
`load` class method on `Calendar`. The `load_cached` variant of this method
|
43
|
+
caches the calendars by name after loading them, to avoid reading and
|
44
|
+
parsing the config file multiple times.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
calendar = Business::Calendar.load("weekdays")
|
48
|
+
calendar = Business::Calendar.load_cached("weekdays")
|
49
|
+
```
|
50
|
+
|
51
|
+
### Checking for business days
|
52
|
+
|
53
|
+
To check whether a given date is a business day (falls on one of the specified
|
54
|
+
working days, and is not a holiday), use the `business_day?` method on
|
55
|
+
`Calendar`.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
calendar.business_day?(Date.parse("Monday, 9 June 2014"))
|
59
|
+
# => true
|
60
|
+
calendar.business_day?(Date.parse("Sunday, 8 June 2014"))
|
61
|
+
# => false
|
62
|
+
```
|
63
|
+
|
64
|
+
### Business day arithmetic
|
65
|
+
|
66
|
+
The `add_business_days` and `subtract_business_days` are used to perform
|
67
|
+
business day arithemtic on dates.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
date = Date.parse("Thursday, 12 June 2014")
|
71
|
+
calendar.add_business_days(date, 4).strftime("%A, %d %B %Y")
|
72
|
+
# => "Wednesday, 18 June 2014"
|
73
|
+
calendar.subtract_business_days(date, 4).strftime("%A, %d %B %Y")
|
74
|
+
# => "Friday, 06 June 2014"
|
75
|
+
```
|
76
|
+
|
77
|
+
The `roll_forward` and `roll_backward` methods snap a date to a nearby business
|
78
|
+
day. If provided with a business day, they will return that date. Otherwise,
|
79
|
+
they will advance (forward for `roll_forward` and backward for `roll_backward`)
|
80
|
+
until a business day is found.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
date = Date.parse("Saturday, 14 June 2014")
|
84
|
+
calendar.roll_forward(date).strftime("%A, %d %B %Y")
|
85
|
+
# => "Monday, 16 June 2014"
|
86
|
+
calendar.roll_backward(date).strftime("%A, %d %B %Y")
|
87
|
+
# => "Friday, 13 June 2014"
|
88
|
+
```
|
89
|
+
|
90
|
+
To count the number of business days between two dates, pass the dates to
|
91
|
+
`business_days_between`. This method counts from start of the first date to
|
92
|
+
start of the second date. So, assuming no holidays, there would be two business
|
93
|
+
days between a Monday and a Wednesday.
|
6
94
|
|
7
95
|
```ruby
|
8
|
-
|
9
|
-
date
|
10
|
-
|
11
|
-
# => 2013-10-21
|
96
|
+
date = Date.parse("Saturday, 14 June 2014")
|
97
|
+
calendar.business_days_between(date, date + 7)
|
98
|
+
# => 5
|
12
99
|
```
|
13
100
|
|
data/business.gemspec
CHANGED
@@ -8,9 +8,10 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Business::VERSION
|
9
9
|
spec.authors = ["Harry Marr"]
|
10
10
|
spec.email = ["engineering@gocardless.com"]
|
11
|
-
spec.description = %q{Date calculations based on business calendars}
|
12
11
|
spec.summary = %q{Date calculations based on business calendars}
|
12
|
+
spec.description = %q{Date calculations based on business calendars}
|
13
13
|
spec.homepage = "https://github.com/gocardless/business"
|
14
|
+
spec.licenses = ["MIT"]
|
14
15
|
|
15
16
|
spec.files = `git ls-files`.split($/)
|
16
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -18,5 +19,5 @@ Gem::Specification.new do |spec|
|
|
18
19
|
spec.require_paths = ["lib"]
|
19
20
|
|
20
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
-
spec.add_development_dependency "rspec", "~>
|
22
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
22
23
|
end
|
data/lib/business/calendar.rb
CHANGED
@@ -6,7 +6,7 @@ module Business
|
|
6
6
|
path = File.join(File.dirname(__FILE__), 'data', "#{calendar}.yml")
|
7
7
|
raise "No such calendar '#{calendar}'" unless File.exists?(path)
|
8
8
|
yaml = YAML.load_file(path)
|
9
|
-
self.new(holidays: yaml['holidays'],
|
9
|
+
self.new(holidays: yaml['holidays'], working_days: yaml['working_days'])
|
10
10
|
end
|
11
11
|
|
12
12
|
@lock = Mutex.new
|
@@ -22,18 +22,18 @@ module Business
|
|
22
22
|
|
23
23
|
DAY_NAMES = %( mon tue wed thu fri sat sun )
|
24
24
|
|
25
|
-
attr_reader :
|
25
|
+
attr_reader :working_days, :holidays
|
26
26
|
|
27
27
|
def initialize(config)
|
28
|
-
|
28
|
+
set_working_days(config[:working_days])
|
29
29
|
set_holidays(config[:holidays])
|
30
30
|
end
|
31
31
|
|
32
|
-
# Return true if the date given is a business day (typically that
|
32
|
+
# Return true if the date given is a business day (typically that meanss a
|
33
33
|
# non-weekend day) and not a holiday.
|
34
34
|
def business_day?(date)
|
35
35
|
date = date.to_date
|
36
|
-
return false unless
|
36
|
+
return false unless working_days.include?(date.strftime('%a').downcase)
|
37
37
|
return false if holidays.include?(date)
|
38
38
|
true
|
39
39
|
end
|
@@ -114,13 +114,13 @@ module Business
|
|
114
114
|
num_full_weeks, remaining_days = (date2 - date1).to_i.divmod(7)
|
115
115
|
|
116
116
|
# First estimate for full week range based on # biz days in a week
|
117
|
-
num_biz_days = num_full_weeks *
|
117
|
+
num_biz_days = num_full_weeks * working_days.length
|
118
118
|
|
119
119
|
full_weeks_range = (date1...(date2 - remaining_days))
|
120
120
|
num_biz_days -= holidays.count do |holiday|
|
121
121
|
in_range = full_weeks_range.cover?(holiday)
|
122
122
|
# Only pick a holiday if its on a working day (e.g., not a weekend)
|
123
|
-
on_biz_day =
|
123
|
+
on_biz_day = working_days.include?(holiday.strftime('%a').downcase)
|
124
124
|
in_range && on_biz_day
|
125
125
|
end
|
126
126
|
|
@@ -133,9 +133,9 @@ module Business
|
|
133
133
|
date.is_a?(Date) ? 1 : 3600 * 24
|
134
134
|
end
|
135
135
|
|
136
|
-
# Internal method for assigning
|
137
|
-
def
|
138
|
-
@
|
136
|
+
# Internal method for assigning working days from a calendar config.
|
137
|
+
def set_working_days(working_days)
|
138
|
+
@working_days = (working_days || default_working_days).map do |day|
|
139
139
|
day.downcase.strip[0..2].tap do |normalised_day|
|
140
140
|
raise "Invalid day #{day}" unless DAY_NAMES.include?(normalised_day)
|
141
141
|
end
|
@@ -147,8 +147,8 @@ module Business
|
|
147
147
|
@holidays = (holidays || []).map { |holiday| Date.parse(holiday) }
|
148
148
|
end
|
149
149
|
|
150
|
-
# If no
|
151
|
-
def
|
150
|
+
# If no working days are provided in the calendar config, these are used.
|
151
|
+
def default_working_days
|
152
152
|
%w( mon tue wed thu fri )
|
153
153
|
end
|
154
154
|
end
|
data/lib/business/data/bacs.yml
CHANGED
data/lib/business/data/sepa.yml
CHANGED
data/lib/business/version.rb
CHANGED
data/spec/calendar_spec.rb
CHANGED
@@ -7,51 +7,51 @@ describe Business::Calendar do
|
|
7
7
|
subject { Business::Calendar.load("weekdays") }
|
8
8
|
|
9
9
|
it "loads the yaml file" do
|
10
|
-
YAML.
|
11
|
-
path.
|
12
|
-
|
10
|
+
expect(YAML).to receive(:load_file) { |path|
|
11
|
+
expect(path).to match(/weekdays\.yml$/)
|
12
|
+
}.and_return({})
|
13
13
|
subject
|
14
14
|
end
|
15
15
|
|
16
|
-
it {
|
16
|
+
it { is_expected.to be_a Business::Calendar }
|
17
17
|
end
|
18
18
|
|
19
19
|
context "when given an invalid calendar" do
|
20
20
|
subject { Business::Calendar.load("invalid-calendar") }
|
21
|
-
specify {
|
21
|
+
specify { expect{ subject }.to raise_error }
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
describe "#
|
25
|
+
describe "#set_working_days" do
|
26
26
|
let(:calendar) { Business::Calendar.new({}) }
|
27
|
-
let(:
|
28
|
-
subject { calendar.
|
27
|
+
let(:working_days) { [] }
|
28
|
+
subject { calendar.set_working_days(working_days) }
|
29
29
|
|
30
|
-
context "when given valid
|
31
|
-
let(:
|
30
|
+
context "when given valid working days" do
|
31
|
+
let(:working_days) { %w( mon fri ) }
|
32
32
|
before { subject }
|
33
33
|
|
34
34
|
it "assigns them" do
|
35
|
-
calendar.
|
35
|
+
expect(calendar.working_days).to eq(working_days)
|
36
36
|
end
|
37
37
|
|
38
38
|
context "that are unnormalised" do
|
39
|
-
let(:
|
39
|
+
let(:working_days) { %w( Monday Friday ) }
|
40
40
|
it "normalises them" do
|
41
|
-
calendar.
|
41
|
+
expect(calendar.working_days).to eq(%w( mon fri ))
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
context "when given an invalid business day" do
|
47
|
-
let(:
|
48
|
-
specify {
|
47
|
+
let(:working_days) { %w( Notaday ) }
|
48
|
+
specify { expect{ subject }.to raise_exception }
|
49
49
|
end
|
50
50
|
|
51
51
|
context "when given nil" do
|
52
|
-
let(:
|
52
|
+
let(:working_days) { nil }
|
53
53
|
it "uses the default business days" do
|
54
|
-
calendar.
|
54
|
+
expect(calendar.working_days).to eq(calendar.default_working_days)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -65,16 +65,16 @@ describe Business::Calendar do
|
|
65
65
|
context "when given valid business days" do
|
66
66
|
let(:holidays) { ["1st Jan, 2013"] }
|
67
67
|
|
68
|
-
it {
|
68
|
+
it { is_expected.not_to be_empty }
|
69
69
|
|
70
70
|
it "converts them to Date objects" do
|
71
|
-
subject.each { |h| h.
|
71
|
+
subject.each { |h| expect(h).to be_a Date }
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
context "when given nil" do
|
76
76
|
let(:holidays) { nil }
|
77
|
-
it {
|
77
|
+
it { is_expected.to be_empty }
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -90,17 +90,17 @@ describe Business::Calendar do
|
|
90
90
|
|
91
91
|
context "when given a business day" do
|
92
92
|
let(:day) { date_class.parse("9am, Wednesday 2nd Jan, 2013") }
|
93
|
-
it {
|
93
|
+
it { is_expected.to be_truthy }
|
94
94
|
end
|
95
95
|
|
96
96
|
context "when given a non-business day" do
|
97
97
|
let(:day) { date_class.parse("9am, Saturday 5th Jan, 2013") }
|
98
|
-
it {
|
98
|
+
it { is_expected.to be_falsey }
|
99
99
|
end
|
100
100
|
|
101
101
|
context "when given a business day that is a holiday" do
|
102
102
|
let(:day) { date_class.parse("9am, Tuesday 1st Jan, 2013") }
|
103
|
-
it {
|
103
|
+
it { is_expected.to be_falsey }
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -112,18 +112,18 @@ describe Business::Calendar do
|
|
112
112
|
|
113
113
|
context "given a business day" do
|
114
114
|
let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
|
115
|
-
it {
|
115
|
+
it { is_expected.to eq(date) }
|
116
116
|
end
|
117
117
|
|
118
118
|
context "given a non-business day" do
|
119
119
|
context "with a business day following it" do
|
120
120
|
let(:date) { date_class.parse("Tuesday 1st Jan, 2013") }
|
121
|
-
it {
|
121
|
+
it { is_expected.to eq(date + day_interval) }
|
122
122
|
end
|
123
123
|
|
124
124
|
context "followed by another non-business day" do
|
125
125
|
let(:date) { date_class.parse("Saturday 5th Jan, 2013") }
|
126
|
-
it {
|
126
|
+
it { is_expected.to eq(date + 2 * day_interval) }
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
@@ -136,18 +136,18 @@ describe Business::Calendar do
|
|
136
136
|
|
137
137
|
context "given a business day" do
|
138
138
|
let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
|
139
|
-
it {
|
139
|
+
it { is_expected.to eq(date) }
|
140
140
|
end
|
141
141
|
|
142
142
|
context "given a non-business day" do
|
143
143
|
context "with a business day preceeding it" do
|
144
144
|
let(:date) { date_class.parse("Tuesday 1st Jan, 2013") }
|
145
|
-
it {
|
145
|
+
it { is_expected.to eq(date - day_interval) }
|
146
146
|
end
|
147
147
|
|
148
148
|
context "preceeded by another non-business day" do
|
149
149
|
let(:date) { date_class.parse("Sunday 6th Jan, 2013") }
|
150
|
-
it {
|
150
|
+
it { is_expected.to eq(date - 2 * day_interval) }
|
151
151
|
end
|
152
152
|
end
|
153
153
|
end
|
@@ -160,18 +160,18 @@ describe Business::Calendar do
|
|
160
160
|
|
161
161
|
context "given a business day" do
|
162
162
|
let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
|
163
|
-
it {
|
163
|
+
it { is_expected.to eq(date + day_interval) }
|
164
164
|
end
|
165
165
|
|
166
166
|
context "given a non-business day" do
|
167
167
|
context "with a business day following it" do
|
168
168
|
let(:date) { date_class.parse("Tuesday 1st Jan, 2013") }
|
169
|
-
it {
|
169
|
+
it { is_expected.to eq(date + day_interval) }
|
170
170
|
end
|
171
171
|
|
172
172
|
context "followed by another non-business day" do
|
173
173
|
let(:date) { date_class.parse("Saturday 5th Jan, 2013") }
|
174
|
-
it {
|
174
|
+
it { is_expected.to eq(date + 2 * day_interval) }
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
@@ -186,23 +186,23 @@ describe Business::Calendar do
|
|
186
186
|
context "given a business day" do
|
187
187
|
context "and a period that includes only business days" do
|
188
188
|
let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
|
189
|
-
it {
|
189
|
+
it { is_expected.to eq(date + delta * day_interval) }
|
190
190
|
end
|
191
191
|
|
192
192
|
context "and a period that includes a weekend" do
|
193
193
|
let(:date) { date_class.parse("Friday 4th Jan, 2013") }
|
194
|
-
it {
|
194
|
+
it { is_expected.to eq(date + (delta + 2) * day_interval) }
|
195
195
|
end
|
196
196
|
|
197
197
|
context "and a period that includes a holiday day" do
|
198
198
|
let(:date) { date_class.parse("Monday 31st Dec, 2012") }
|
199
|
-
it {
|
199
|
+
it { is_expected.to eq(date + (delta + 1) * day_interval) }
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
203
|
context "given a non-business day" do
|
204
204
|
let(:date) { date_class.parse("Tuesday 1st Jan, 2013") }
|
205
|
-
it {
|
205
|
+
it { is_expected.to eq(date + (delta + 1) * day_interval) }
|
206
206
|
end
|
207
207
|
end
|
208
208
|
|
@@ -216,23 +216,23 @@ describe Business::Calendar do
|
|
216
216
|
context "given a business day" do
|
217
217
|
context "and a period that includes only business days" do
|
218
218
|
let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
|
219
|
-
it {
|
219
|
+
it { is_expected.to eq(date - delta * day_interval) }
|
220
220
|
end
|
221
221
|
|
222
222
|
context "and a period that includes a weekend" do
|
223
223
|
let(:date) { date_class.parse("Monday 31st Dec, 2012") }
|
224
|
-
it {
|
224
|
+
it { is_expected.to eq(date - (delta + 2) * day_interval) }
|
225
225
|
end
|
226
226
|
|
227
227
|
context "and a period that includes a holiday day" do
|
228
228
|
let(:date) { date_class.parse("Friday 4th Jan, 2013") }
|
229
|
-
it {
|
229
|
+
it { is_expected.to eq(date - (delta + 1) * day_interval) }
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
233
|
context "given a non-business day" do
|
234
234
|
let(:date) { date_class.parse("Thursday 3rd Jan, 2013") }
|
235
|
-
it {
|
235
|
+
it { is_expected.to eq(date - (delta + 1) * day_interval) }
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
@@ -250,35 +250,35 @@ describe Business::Calendar do
|
|
250
250
|
context "ending on a business day" do
|
251
251
|
context "including only business days" do
|
252
252
|
let(:date_2) { date_class.parse("Thu 5/6/2014") }
|
253
|
-
it {
|
253
|
+
it { is_expected.to eq(3) }
|
254
254
|
end
|
255
255
|
|
256
256
|
context "including only business days & weekend days" do
|
257
257
|
let(:date_2) { date_class.parse("Mon 9/6/2014") }
|
258
|
-
it {
|
258
|
+
it { is_expected.to eq(5) }
|
259
259
|
end
|
260
260
|
|
261
261
|
context "including only business days & holidays" do
|
262
262
|
let(:date_1) { date_class.parse("Mon 9/6/2014") }
|
263
263
|
let(:date_2) { date_class.parse("Fri 13/6/2014") }
|
264
|
-
it {
|
264
|
+
it { is_expected.to eq(3) }
|
265
265
|
end
|
266
266
|
|
267
267
|
context "including business, weekend days, and holidays" do
|
268
268
|
let(:date_2) { date_class.parse("Fri 13/6/2014") }
|
269
|
-
it {
|
269
|
+
it { is_expected.to eq(8) }
|
270
270
|
end
|
271
271
|
end
|
272
272
|
|
273
273
|
context "ending on a weekend day" do
|
274
274
|
context "including only business days & weekend days" do
|
275
275
|
let(:date_2) { date_class.parse("Sun 8/6/2014") }
|
276
|
-
it {
|
276
|
+
it { is_expected.to eq(5) }
|
277
277
|
end
|
278
278
|
|
279
279
|
context "including business, weekend days, and holidays" do
|
280
280
|
let(:date_2) { date_class.parse("Sat 14/6/2014") }
|
281
|
-
it {
|
281
|
+
it { is_expected.to eq(9) }
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
@@ -286,12 +286,12 @@ describe Business::Calendar do
|
|
286
286
|
context "including only business days & holidays" do
|
287
287
|
let(:date_1) { date_class.parse("Mon 9/6/2014") }
|
288
288
|
let(:date_2) { date_class.parse("Thu 12/6/2014") }
|
289
|
-
it {
|
289
|
+
it { is_expected.to eq(3) }
|
290
290
|
end
|
291
291
|
|
292
292
|
context "including business, weekend days, and holidays" do
|
293
293
|
let(:date_2) { date_class.parse("Thu 12/6/2014") }
|
294
|
-
it {
|
294
|
+
it { is_expected.to eq(8) }
|
295
295
|
end
|
296
296
|
end
|
297
297
|
end
|
@@ -303,31 +303,31 @@ describe Business::Calendar do
|
|
303
303
|
|
304
304
|
context "including only business days & weekend days" do
|
305
305
|
let(:date_2) { date_class.parse("Mon 9/6/2014") }
|
306
|
-
it {
|
306
|
+
it { is_expected.to eq(0) }
|
307
307
|
end
|
308
308
|
|
309
309
|
context "including business, weekend days, and holidays" do
|
310
310
|
let(:date_2) { date_class.parse("Fri 13/6/2014") }
|
311
|
-
it {
|
311
|
+
it { is_expected.to eq(3) }
|
312
312
|
end
|
313
313
|
end
|
314
314
|
|
315
315
|
context "ending on a weekend day" do
|
316
316
|
context "including only business days & weekend days" do
|
317
317
|
let(:date_2) { date_class.parse("Sun 8/6/2014") }
|
318
|
-
it {
|
318
|
+
it { is_expected.to eq(0) }
|
319
319
|
end
|
320
320
|
|
321
321
|
context "including business, weekend days, and holidays" do
|
322
322
|
let(:date_2) { date_class.parse("Sat 14/6/2014") }
|
323
|
-
it {
|
323
|
+
it { is_expected.to eq(4) }
|
324
324
|
end
|
325
325
|
end
|
326
326
|
|
327
327
|
context "ending on a holiday" do
|
328
328
|
context "including business, weekend days, and holidays" do
|
329
329
|
let(:date_2) { date_class.parse("Thu 12/6/2014") }
|
330
|
-
it {
|
330
|
+
it { is_expected.to eq(3) }
|
331
331
|
end
|
332
332
|
end
|
333
333
|
end
|
@@ -339,19 +339,19 @@ describe Business::Calendar do
|
|
339
339
|
|
340
340
|
context "including only business days & holidays" do
|
341
341
|
let(:date_2) { date_class.parse("Fri 13/6/2014") }
|
342
|
-
it {
|
342
|
+
it { is_expected.to eq(0) }
|
343
343
|
end
|
344
344
|
|
345
345
|
context "including business, weekend days, and holidays" do
|
346
346
|
let(:date_2) { date_class.parse("Thu 19/6/2014") }
|
347
|
-
it {
|
347
|
+
it { is_expected.to eq(3) }
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
351
351
|
context "ending on a weekend day" do
|
352
352
|
context "including business, weekend days, and holidays" do
|
353
353
|
let(:date_2) { date_class.parse("Sun 15/6/2014") }
|
354
|
-
it {
|
354
|
+
it { is_expected.to eq(1) }
|
355
355
|
end
|
356
356
|
end
|
357
357
|
|
@@ -359,12 +359,12 @@ describe Business::Calendar do
|
|
359
359
|
context "including only business days & holidays" do
|
360
360
|
let(:date_1) { date_class.parse("Wed 18/6/2014") }
|
361
361
|
let(:date_2) { date_class.parse("Fri 20/6/2014") }
|
362
|
-
it {
|
362
|
+
it { is_expected.to eq(1) }
|
363
363
|
end
|
364
364
|
|
365
365
|
context "including business, weekend days, and holidays" do
|
366
366
|
let(:date_2) { date_class.parse("Wed 18/6/2014") }
|
367
|
-
it {
|
367
|
+
it { is_expected.to eq(3) }
|
368
368
|
end
|
369
369
|
end
|
370
370
|
end
|
@@ -373,12 +373,12 @@ describe Business::Calendar do
|
|
373
373
|
context "for a range less than a week long" do
|
374
374
|
let(:date_1) { date_class.parse("Thu 19/6/2014") }
|
375
375
|
let(:date_2) { date_class.parse("Tue 24/6/2014") }
|
376
|
-
it {
|
376
|
+
it { is_expected.to eq(2) }
|
377
377
|
end
|
378
378
|
context "for a range more than a week long" do
|
379
379
|
let(:date_1) { date_class.parse("Mon 16/6/2014") }
|
380
380
|
let(:date_2) { date_class.parse("Tue 24/6/2014") }
|
381
|
-
it {
|
381
|
+
it { is_expected.to eq(4) }
|
382
382
|
end
|
383
383
|
end
|
384
384
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: business
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Marr
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '3.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '3.0'
|
41
41
|
description: Date calculations based on business calendars
|
42
42
|
email:
|
43
43
|
- engineering@gocardless.com
|
@@ -47,6 +47,7 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- .gitignore
|
49
49
|
- Gemfile
|
50
|
+
- LICENSE
|
50
51
|
- README.md
|
51
52
|
- business.gemspec
|
52
53
|
- lib/business.rb
|
@@ -57,7 +58,8 @@ files:
|
|
57
58
|
- lib/business/version.rb
|
58
59
|
- spec/calendar_spec.rb
|
59
60
|
homepage: https://github.com/gocardless/business
|
60
|
-
licenses:
|
61
|
+
licenses:
|
62
|
+
- MIT
|
61
63
|
metadata: {}
|
62
64
|
post_install_message:
|
63
65
|
rdoc_options: []
|