scheduling 0.1.1 → 0.1.2
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.
- data/ChangeLog.rdoc +5 -1
- data/README.rdoc +1 -1
- data/lib/scheduling.rb +1 -0
- data/lib/scheduling/regularity/quarterly.rb +82 -0
- data/lib/scheduling/version.rb +1 -1
- data/spec/regularity/quarterly_spec.rb +164 -0
- metadata +7 -4
data/ChangeLog.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
== Description
|
8
8
|
|
9
|
-
|
9
|
+
Classes for making schedules, that are regular (yearly, monthly, quarterly, etc.), irregular, or both (compound). Once a schedule is made, and given a target date range, the date of all occurances can be determined.
|
10
10
|
|
11
11
|
== Features
|
12
12
|
|
data/lib/scheduling.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
class Date
|
2
|
+
def self.q1(year)
|
3
|
+
Date.new(year,1)
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.q2(year)
|
7
|
+
Date.new(year,4)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.q3(year)
|
11
|
+
Date.new(year,7)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.q4(year)
|
15
|
+
Date.new(year,10)
|
16
|
+
end
|
17
|
+
|
18
|
+
def quarter
|
19
|
+
1 + ((month - 1) / 3)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.quarterly year, quarter = 1, qday = 1
|
23
|
+
case quarter
|
24
|
+
when 1
|
25
|
+
self.q1(year) + (qday - 1)
|
26
|
+
when 2
|
27
|
+
self.q2(year) + (qday - 1)
|
28
|
+
when 3
|
29
|
+
self.q3(year) + (qday - 1)
|
30
|
+
when 4
|
31
|
+
self.q4(year) + (qday - 1)
|
32
|
+
else
|
33
|
+
raise ArgumentError, "quarter #{quarter} is not 1-4"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def qday
|
38
|
+
1 + (self - Date.quarterly(self.year, quarter)).to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def next_quarter count = 1
|
42
|
+
raise ArgumentError, "count #{count} is < 1" if count < 1
|
43
|
+
|
44
|
+
quarter = self.quarter + count % 4
|
45
|
+
year = self.year + count / 4
|
46
|
+
|
47
|
+
if quarter > 4
|
48
|
+
year += 1
|
49
|
+
quarter = (quarter - 4)
|
50
|
+
end
|
51
|
+
|
52
|
+
Date.quarterly(year, quarter, self.qday)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Scheduling
|
57
|
+
class Quarterly < Struct.new(:qday)
|
58
|
+
def occurances time_range
|
59
|
+
raise RangeDecreasingError if time_range.decreasing?
|
60
|
+
cur = Date.quarterly(time_range.min.year, time_range.min.quarter, qday)
|
61
|
+
|
62
|
+
start = time_range.min
|
63
|
+
if cur < start
|
64
|
+
cur = cur.next_quarter
|
65
|
+
end
|
66
|
+
|
67
|
+
occurances = []
|
68
|
+
|
69
|
+
stop = time_range.last
|
70
|
+
if time_range.exclude_end?
|
71
|
+
stop -= 1
|
72
|
+
end
|
73
|
+
|
74
|
+
while cur <= stop
|
75
|
+
occurances.push cur
|
76
|
+
cur = cur.next_quarter
|
77
|
+
end
|
78
|
+
|
79
|
+
return occurances
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/scheduling/version.rb
CHANGED
@@ -0,0 +1,164 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Date do
|
4
|
+
|
5
|
+
describe '.q1' do
|
6
|
+
it 'should produce a date starting Jan 1 of the given year' do
|
7
|
+
[1910, 2000, 2111].each do |year|
|
8
|
+
date = Date.q1(year)
|
9
|
+
date.month.should eq(1)
|
10
|
+
date.day.should eq(1)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.q2' do
|
16
|
+
it 'should produce a date starting Apr 1 of the given year' do
|
17
|
+
[1910, 2000, 2111].each do |year|
|
18
|
+
date = Date.q2(year)
|
19
|
+
date.month.should eq(4)
|
20
|
+
date.day.should eq(1)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '.q3' do
|
26
|
+
it 'should produce a date starting July 1 of the given year' do
|
27
|
+
[1910, 2000, 2111].each do |year|
|
28
|
+
date = Date.q3(year)
|
29
|
+
date.month.should eq(7)
|
30
|
+
date.day.should eq(1)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.q4' do
|
36
|
+
it 'should produce a date starting Oct 1 of the given year' do
|
37
|
+
[1910, 2000, 2111].each do |year|
|
38
|
+
date = Date.q4(year)
|
39
|
+
date.month.should eq(10)
|
40
|
+
date.day.should eq(1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#quarter' do
|
46
|
+
it 'should return 1 for quarters 1-3' do
|
47
|
+
[1,2,3].each do |quarter|
|
48
|
+
Date.new(2000,quarter).quarter.should eq(1)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should return 2 for quarters 4-6' do
|
53
|
+
[4,5,6].each do |quarter|
|
54
|
+
Date.new(2000,quarter).quarter.should eq(2)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should return 3 for quarters 7-9' do
|
59
|
+
[7,8,9].each do |quarter|
|
60
|
+
Date.new(2000,quarter).quarter.should eq(3)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should return 4 for quarters 10-12' do
|
65
|
+
[10,11,12].each do |quarter|
|
66
|
+
Date.new(2000,quarter).quarter.should eq(4)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.quarterly' do
|
72
|
+
it 'should produce a Date instance' do
|
73
|
+
Date.quarterly(2000).should be_a Date
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should produce a date with given qday' do
|
77
|
+
[1,10,20,70,89].each do |qday|
|
78
|
+
Date.quarterly(1995,2,qday).qday.should eq(qday)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#qday' do
|
84
|
+
it 'should return the number of days since the start of the last quarter' do
|
85
|
+
[
|
86
|
+
Date.new(2000,3,28),
|
87
|
+
Date.new(1999,10,15),
|
88
|
+
Date.new(2006,8,11),
|
89
|
+
Date.new(2045,12,31)
|
90
|
+
].each do |date|
|
91
|
+
date.qday.should eq(1 + (date - Date.quarterly(date.year, date.quarter)))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#next_quarter' do
|
97
|
+
it 'should return the a date that is number of quarters in the future' do
|
98
|
+
[
|
99
|
+
#{ :start => Date.quarterly(2000,3,28), :q_incr => 2, :expected => Date.quarterly(2001, 1, 28) },
|
100
|
+
#{ :start => Date.quarterly(2012,1), :q_incr => 5, :expected => Date.quarterly(2013, 2) },
|
101
|
+
#{ :start => Date.quarterly(2030,4,45), :q_incr => 11, :expected => Date.quarterly(2033, 3, 45) },
|
102
|
+
].each do |hash|
|
103
|
+
hash[:start].next_quarter(hash[:q_incr]).should eq(hash[:expected])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe Quarterly do
|
110
|
+
describe '#occurances' do
|
111
|
+
context 'time range spans less than 1 quarter' do
|
112
|
+
context 'original time not in qday range' do
|
113
|
+
it 'should return empty array' do
|
114
|
+
[
|
115
|
+
{:qday => 15, :range => Date.quarterly(2003,1,16)..Date.quarterly(2003,2,14)},
|
116
|
+
{:qday => 15, :range => Date.quarterly(2003,1,16)...Date.quarterly(2003,2,15)},
|
117
|
+
{:qday => 2, :range => Date.new(2021,1,3)...Date.new(2021,2,1)},
|
118
|
+
].each do |hash|
|
119
|
+
Quarterly.new(hash[:qday]).occurances(hash[:range]).should be_empty
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'original time is in qday range' do
|
125
|
+
it 'should return array with 1 element' do
|
126
|
+
[
|
127
|
+
{:qday => 15, :range => Date.quarterly(2003,1,16)...Date.quarterly(2003,2,16)},
|
128
|
+
{:qday => 15, :range => Date.quarterly(2003,1,14)...Date.quarterly(2003,2,15)},
|
129
|
+
{:qday => 10, :range => Date.quarterly(2003,3,88)..Date.quarterly(2003,4,22)},
|
130
|
+
{:qday => 22, :range => Date.quarterly(2003,3)...Date.quarterly(2003,4)},
|
131
|
+
].each do |hash|
|
132
|
+
Quarterly.new(hash[:qday]).occurances(hash[:range]).count.should eq(1)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'time range spans more than 1 quarter but less than 2' do
|
139
|
+
context 'original time not in qday range' do
|
140
|
+
it 'should return array with 1 element' do
|
141
|
+
[
|
142
|
+
{:qday => 15, :range => Date.quarterly(2003,1,16)..Date.quarterly(2003,3,14)},
|
143
|
+
{:qday => 15, :range => Date.quarterly(2003,1,14)...Date.quarterly(2003,2,15)},
|
144
|
+
{:qday => 2, :range => Date.quarterly(2020,4,3)...Date.quarterly(2021,1,5)},
|
145
|
+
].each do |hash|
|
146
|
+
Quarterly.new(hash[:qday]).occurances(hash[:range]).count.should eq(1)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'original time is in qday range' do
|
152
|
+
it 'should return array with 2 elements' do
|
153
|
+
[
|
154
|
+
{:qday => 15, :range => Date.quarterly(2003,1,15)...Date.quarterly(2003,3,15)},
|
155
|
+
{:qday => 15, :range => Date.quarterly(2003,1,16)...Date.quarterly(2003,3,16)},
|
156
|
+
{:qday => 22, :range => Date.quarterly(2003,3,1)...Date.quarterly(2004)},
|
157
|
+
].each do |hash|
|
158
|
+
Quarterly.new(hash[:qday]).occurances(hash[:range]).count.should eq(2)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scheduling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/scheduling.rb
|
112
112
|
- lib/scheduling/intersection.rb
|
113
113
|
- lib/scheduling/regularity/monthly.rb
|
114
|
+
- lib/scheduling/regularity/quarterly.rb
|
114
115
|
- lib/scheduling/regularity/yearly.rb
|
115
116
|
- lib/scheduling/schedule/compound_schedule.rb
|
116
117
|
- lib/scheduling/schedule/irregular_schedule.rb
|
@@ -119,6 +120,7 @@ files:
|
|
119
120
|
- scheduling.gemspec
|
120
121
|
- spec/intersection_spec.rb
|
121
122
|
- spec/regularity/monthly_spec.rb
|
123
|
+
- spec/regularity/quarterly_spec.rb
|
122
124
|
- spec/regularity/yearly_spec.rb
|
123
125
|
- spec/schedule/compound_schedule_spec.rb
|
124
126
|
- spec/schedule/irregular_schedule_spec.rb
|
@@ -140,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
142
|
version: '0'
|
141
143
|
segments:
|
142
144
|
- 0
|
143
|
-
hash: -
|
145
|
+
hash: -1329761715509626376
|
144
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
147
|
none: false
|
146
148
|
requirements:
|
@@ -149,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
151
|
version: '0'
|
150
152
|
segments:
|
151
153
|
- 0
|
152
|
-
hash: -
|
154
|
+
hash: -1329761715509626376
|
153
155
|
requirements: []
|
154
156
|
rubyforge_project:
|
155
157
|
rubygems_version: 1.8.23
|
@@ -159,6 +161,7 @@ summary: Make schedules, regular (yearly, monthly, etc.) or otherwise.
|
|
159
161
|
test_files:
|
160
162
|
- spec/intersection_spec.rb
|
161
163
|
- spec/regularity/monthly_spec.rb
|
164
|
+
- spec/regularity/quarterly_spec.rb
|
162
165
|
- spec/regularity/yearly_spec.rb
|
163
166
|
- spec/schedule/compound_schedule_spec.rb
|
164
167
|
- spec/schedule/irregular_schedule_spec.rb
|