business 0.1.0 → 1.0.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 +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: []
|