fat_core 0.1.10 → 0.1.11

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.
@@ -57,7 +57,7 @@ class Period
57
57
  # the same date will sort by last date, thus, from smallest to largest in
58
58
  # size.
59
59
  def <=>(other)
60
- [first, last] <=> [other.first, other.last]
60
+ [first, size] <=> [other.first, other.size]
61
61
  end
62
62
 
63
63
  # Comparable does not include this.
@@ -1,7 +1,7 @@
1
1
  module FatCore
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- PATCH = 10
4
+ PATCH = 11
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
7
7
  end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Date do
@@ -10,6 +11,189 @@ describe Date do
10
11
 
11
12
  describe "class methods" do
12
13
 
14
+ describe "date arithmetic" do
15
+ it "should know the number of days in a month" do
16
+ expect(Date.days_in_month(2000, 1)).to eq 31
17
+ expect(Date.days_in_month(1900, 2)).to eq 28
18
+ expect(Date.days_in_month(2000, 2)).to eq 29
19
+ expect(Date.days_in_month(2001, 2)).to eq 28
20
+ expect(Date.days_in_month(2004, 2)).to eq 29
21
+ expect(Date.days_in_month(2004, 3)).to eq 31
22
+ expect(Date.days_in_month(2004, 4)).to eq 30
23
+ expect(Date.days_in_month(2004, 5)).to eq 31
24
+ expect(Date.days_in_month(2004, 6)).to eq 30
25
+ expect(Date.days_in_month(2004, 7)).to eq 31
26
+ expect(Date.days_in_month(2004, 8)).to eq 31
27
+ expect(Date.days_in_month(2004, 9)).to eq 30
28
+ expect(Date.days_in_month(2004, 10)).to eq 31
29
+ expect(Date.days_in_month(2004, 11)).to eq 30
30
+ expect(Date.days_in_month(2004, 12)).to eq 31
31
+ expect { Date.days_in_month(2004, 13) }.to raise_error ArgumentError
32
+ end
33
+
34
+ it "should know the nth weekday in a year, month" do
35
+ # Sunday is 0, Saturday is 6
36
+ # January 2014
37
+ # Su Mo Tu We Th Fr Sa
38
+ # 1 2 3 4
39
+ # 5 6 7 8 9 10 11
40
+ # 12 13 14 15 16 17 18
41
+ # 19 20 21 22 23 24 25
42
+ # 26 27 28 29 30 31
43
+
44
+ # First Monday
45
+ expect(Date.nth_wday_in_year_month(1, 1, 2014, 1)).to eq Date.parse('2014-01-06')
46
+ # Second Monday
47
+ expect(Date.nth_wday_in_year_month(2, 1, 2014, 1)).to eq Date.parse('2014-01-13')
48
+ # Third Sunday
49
+ expect(Date.nth_wday_in_year_month(3, 0, 2014, 1)).to eq Date.parse('2014-01-19')
50
+ # Third Sunday (float floored)
51
+ expect(Date.nth_wday_in_year_month(3.2, 0, 2014, 1)).to eq Date.parse('2014-01-19')
52
+ # Negative wday counts from end: Last Sunday
53
+ expect(Date.nth_wday_in_year_month(-1, 0, 2014, 1)).to eq Date.parse('2014-01-26')
54
+ expect(Date.nth_wday_in_year_month(-3, 0, 2014, 1)).to eq Date.parse('2014-01-12')
55
+ # Negative wday counts from end: Last Thursday
56
+ expect(Date.nth_wday_in_year_month(-1, 4, 2014, 1)).to eq Date.parse('2014-01-30')
57
+
58
+ # Exceptions
59
+ expect {
60
+ # N is zero
61
+ Date.nth_wday_in_year_month(0, 6, 2014, 1)
62
+ }.to raise_error ArgumentError
63
+ expect {
64
+ # Wday too big
65
+ Date.nth_wday_in_year_month(3, 7, 2014, 1)
66
+ }.to raise_error ArgumentError
67
+ expect {
68
+ # Month too big
69
+ Date.nth_wday_in_year_month(3, 1, 2014, 13)
70
+ }.to raise_error ArgumentError
71
+ end
72
+
73
+ it "should know Easter for a given year" do
74
+ # Grabbed these dates of Easter from
75
+ # http://tlarsen2.tripod.com/thomaslarsen/easterdates.html
76
+ easters = {
77
+ 2000 => '2000-04-23',
78
+ 2001 => '2001-04-15',
79
+ 2002 => '2002-03-31',
80
+ 2003 => '2003-04-20',
81
+ 2004 => '2004-04-11',
82
+ 2005 => '2005-03-27',
83
+ 2006 => '2006-04-16',
84
+ 2007 => '2007-04-08',
85
+ 2008 => '2008-03-23',
86
+ 2009 => '2009-04-12',
87
+ 2010 => '2010-04-04',
88
+ 2011 => '2011-04-24',
89
+ 2012 => '2012-04-08',
90
+ 2013 => '2013-03-31',
91
+ 2014 => '2014-04-20',
92
+ 2015 => '2015-04-05',
93
+ 2016 => '2016-03-27',
94
+ 2017 => '2017-04-16',
95
+ 2018 => '2018-04-01',
96
+ 2019 => '2019-04-21',
97
+ 2020 => '2020-04-12',
98
+ 2021 => '2021-04-04',
99
+ 2022 => '2022-04-17',
100
+ 2023 => '2023-04-09',
101
+ 2024 => '2024-03-31',
102
+ 2025 => '2025-04-20',
103
+ 2026 => '2026-04-05',
104
+ 2027 => '2027-03-28',
105
+ 2028 => '2028-04-16',
106
+ 2029 => '2029-04-01',
107
+ 2030 => '2030-04-21',
108
+ 2031 => '2031-04-13',
109
+ 2032 => '2032-03-28',
110
+ 2033 => '2033-04-17',
111
+ 2034 => '2034-04-09',
112
+ 2035 => '2035-03-25',
113
+ 2036 => '2036-04-13',
114
+ 2037 => '2037-04-05',
115
+ 2038 => '2038-04-25',
116
+ 2039 => '2039-04-10',
117
+ 2040 => '2040-04-01',
118
+ 2041 => '2041-04-21',
119
+ 2042 => '2042-04-06',
120
+ 2043 => '2043-03-29',
121
+ 2044 => '2044-04-17',
122
+ 2045 => '2045-04-09',
123
+ 2046 => '2046-03-25',
124
+ 2047 => '2047-04-14',
125
+ 2048 => '2048-04-05',
126
+ 2049 => '2049-04-18',
127
+ 2050 => '2050-04-10',
128
+ 2051 => '2051-04-02',
129
+ 2052 => '2052-04-21',
130
+ 2053 => '2053-04-06',
131
+ 2054 => '2054-03-29',
132
+ 2055 => '2055-04-18',
133
+ 2056 => '2056-04-02',
134
+ 2057 => '2057-04-22',
135
+ 2058 => '2058-04-14',
136
+ 2059 => '2059-03-30',
137
+ 2060 => '2060-04-18',
138
+ 2061 => '2061-04-10',
139
+ 2062 => '2062-03-26',
140
+ 2063 => '2063-04-15',
141
+ 2064 => '2064-04-06',
142
+ 2065 => '2065-03-29',
143
+ 2066 => '2066-04-11',
144
+ 2067 => '2067-04-03',
145
+ 2068 => '2068-04-22',
146
+ 2069 => '2069-04-14',
147
+ 2070 => '2070-03-30',
148
+ 2071 => '2071-04-19',
149
+ 2072 => '2072-04-10',
150
+ 2073 => '2073-03-26',
151
+ 2074 => '2074-04-15',
152
+ 2075 => '2075-04-07',
153
+ 2076 => '2076-04-19',
154
+ 2077 => '2077-04-11',
155
+ 2078 => '2078-04-03',
156
+ 2079 => '2079-04-23',
157
+ 2080 => '2080-04-07',
158
+ 2081 => '2081-03-30',
159
+ 2082 => '2082-04-19',
160
+ 2083 => '2083-04-04',
161
+ 2084 => '2084-03-26',
162
+ 2085 => '2085-04-15',
163
+ 2086 => '2086-03-31',
164
+ 2087 => '2087-04-20',
165
+ 2088 => '2088-04-11',
166
+ 2089 => '2089-04-03',
167
+ 2090 => '2090-04-16',
168
+ 2091 => '2091-04-08',
169
+ 2092 => '2092-03-30',
170
+ 2093 => '2093-04-12',
171
+ 2094 => '2094-04-04',
172
+ 2095 => '2095-04-24',
173
+ 2096 => '2096-04-15',
174
+ 2097 => '2097-03-31',
175
+ 2098 => '2098-04-20',
176
+ 2099 => '2099-04-12',
177
+ }
178
+ easters.each_pair do |year, date|
179
+ expect(Date.easter(year)).to eq Date.parse(date)
180
+ end
181
+ end
182
+ end
183
+
184
+ describe "parsing" do
185
+ it "should be able to parse an American-style date" do
186
+ expect(Date.parse_american('2/12/2011').iso).to eq('2011-02-12')
187
+ expect(Date.parse_american('2 / 12/ 2011').iso).to eq('2011-02-12')
188
+ expect(Date.parse_american('2 / 1 / 2011').iso).to eq('2011-02-01')
189
+ expect(Date.parse_american(' 2 / 1 / 2011 ').iso).to eq('2011-02-01')
190
+ expect(Date.parse_american(' 2 / 1 / 15 ').iso).to eq('2015-02-01')
191
+ expect {
192
+ Date.parse_american('xx/1/15')
193
+ }.to raise_error ArgumentError
194
+ end
195
+ end
196
+
13
197
  describe "parse_spec" do
14
198
 
15
199
  it "should choke if spec type is neither :from or :to" do
@@ -143,169 +327,473 @@ describe Date do
143
327
  expect(Date.parse_spec('never')).to be_nil
144
328
  end
145
329
  end
146
-
147
- it "should be able to parse an American-style date" do
148
- expect(Date.parse_american('2/12/2011').iso).to eq('2011-02-12')
149
- expect(Date.parse_american('2 / 12/ 2011').iso).to eq('2011-02-12')
150
- expect(Date.parse_american('2 / 1 / 2011').iso).to eq('2011-02-01')
151
- expect(Date.parse_american(' 2 / 1 / 2011 ').iso).to eq('2011-02-01')
152
- expect(Date.parse_american(' 2 / 1 / 15 ').iso).to eq('2015-02-01')
153
- end
154
330
  end
155
331
 
156
332
  describe "instance methods" do
333
+ describe "print as string" do
334
+ it "should be able to print itself as an American-style date" do
335
+ expect(Date.parse('2011-02-12').american).to eq('2/12/2011')
336
+ end
157
337
 
158
- it "should know if its a weekend of a weekday" do
159
- expect(Date.parse('2014-05-17')).to be_weekend
160
- expect(Date.parse('2014-05-17')).to_not be_weekday
161
- expect(Date.parse('2014-05-18')).to be_weekend
162
- expect(Date.parse('2014-05-18')).to_not be_weekday
338
+ it "should be able to print itself in iso form" do
339
+ expect(Date.today.iso).to eq '2012-07-18'
340
+ end
163
341
 
164
- expect(Date.parse('2014-05-22')).to be_weekday
165
- expect(Date.parse('2014-05-22')).to_not be_weekend
166
- end
342
+ it "should be able to print itself in tex_quote form" do
343
+ expect(Date.today.tex_quote).to eq '2012-07-18'
344
+ end
167
345
 
168
- it "should know its pred and succ (for Range)" do
169
- expect(Date.today.pred).to eq (Date.today - 1)
170
- expect(Date.today.succ).to eq (Date.today + 1)
171
- end
346
+ it "should be able to print itself in org form" do
347
+ expect(Date.today.org).to eq('[2012-07-18 Wed]')
348
+ expect((Date.today + 1.day).org).to eq('[2012-07-19 Thu]')
349
+ end
172
350
 
173
- it "should be able to print itself as an American-style date" do
174
- expect(Date.parse('2011-02-12').american).to eq('2/12/2011')
175
- end
351
+ it "should be able to print itself in eng form" do
352
+ expect(Date.today.eng).to eq('July 18, 2012')
353
+ expect((Date.today + 1.day).eng).to eq('July 19, 2012')
354
+ end
176
355
 
177
- it "should be able to print itself in iso form" do
178
- expect(Date.today.iso).to eq '2012-07-18'
356
+ it "should be able to print itself in numeric form" do
357
+ expect(Date.today.num).to eq('20120718')
358
+ expect((Date.today + 1.day).num).to eq('20120719')
359
+ end
179
360
  end
180
361
 
181
- it "should be able to print itself in org form" do
182
- expect(Date.today.org).to eq('[2012-07-18 Wed]')
183
- expect((Date.today + 1.day).org).to eq('[2012-07-19 Thu]')
184
- end
362
+ describe "date arithmetic" do
363
+ it "should know if its the nth weekday in a given month" do
364
+ expect(Date.parse('2014-11-13').nth_wday_in_month?(2, 4, 11)).
365
+ to be true
366
+ expect(Date.parse('2014-11-13').nth_wday_in_month?(-3, 4, 11)).
367
+ to be true
368
+ expect(Date.parse('2014-11-13').nth_wday_in_month?(2, 4, 10)).
369
+ to be false
370
+ end
185
371
 
186
- it "should be able to print itself in eng form" do
187
- expect(Date.today.eng).to eq('July 18, 2012')
188
- expect((Date.today + 1.day).eng).to eq('July 19, 2012')
189
- end
372
+ it "should know if its a weekend or a weekday" do
373
+ expect(Date.parse('2014-05-17')).to be_weekend
374
+ expect(Date.parse('2014-05-17')).to_not be_weekday
375
+ expect(Date.parse('2014-05-18')).to be_weekend
376
+ expect(Date.parse('2014-05-18')).to_not be_weekday
190
377
 
191
- it "should be able to state its quarter" do
192
- expect(Date.today.quarter).to eq(3)
193
- expect(Date.parse('2012-02-29').quarter).to eq(1)
194
- expect(Date.parse('2012-01-01').quarter).to eq(1)
195
- expect(Date.parse('2012-03-31').quarter).to eq(1)
196
- expect(Date.parse('2012-04-01').quarter).to eq(2)
197
- expect(Date.parse('2012-05-15').quarter).to eq(2)
198
- expect(Date.parse('2012-06-30').quarter).to eq(2)
199
- expect(Date.parse('2012-07-01').quarter).to eq(3)
200
- expect(Date.parse('2012-08-15').quarter).to eq(3)
201
- expect(Date.parse('2012-09-30').quarter).to eq(3)
202
- expect(Date.parse('2012-10-01').quarter).to eq(4)
203
- expect(Date.parse('2012-11-15').quarter).to eq(4)
204
- expect(Date.parse('2012-12-31').quarter).to eq(4)
205
- end
378
+ expect(Date.parse('2014-05-22')).to be_weekday
379
+ expect(Date.parse('2014-05-22')).to_not be_weekend
380
+ end
206
381
 
207
- it "should know about years" do
208
- expect(Date.parse('2013-01-01')).to be_beginning_of_year
209
- expect(Date.parse('2013-12-31')).to be_end_of_year
210
- expect(Date.parse('2013-04-01')).to_not be_beginning_of_year
211
- expect(Date.parse('2013-12-30')).to_not be_end_of_year
212
- end
382
+ it "should know its pred and succ (for Range)" do
383
+ expect(Date.today.pred).to eq (Date.today - 1)
384
+ expect(Date.today.succ).to eq (Date.today + 1)
385
+ end
213
386
 
214
- it "should know about quarters" do
215
- expect(Date.parse('2013-01-01')).to be_beginning_of_quarter
216
- expect(Date.parse('2013-12-31')).to be_end_of_quarter
217
- expect(Date.parse('2013-04-01')).to be_beginning_of_quarter
218
- expect(Date.parse('2013-06-30')).to be_end_of_quarter
219
- expect(Date.parse('2013-05-01')).to_not be_beginning_of_quarter
220
- expect(Date.parse('2013-07-31')).to_not be_end_of_quarter
221
- end
387
+ it "should be able to state its quarter" do
388
+ expect(Date.today.quarter).to eq(3)
389
+ expect(Date.parse('2012-02-29').quarter).to eq(1)
390
+ expect(Date.parse('2012-01-01').quarter).to eq(1)
391
+ expect(Date.parse('2012-03-31').quarter).to eq(1)
392
+ expect(Date.parse('2012-04-01').quarter).to eq(2)
393
+ expect(Date.parse('2012-05-15').quarter).to eq(2)
394
+ expect(Date.parse('2012-06-30').quarter).to eq(2)
395
+ expect(Date.parse('2012-07-01').quarter).to eq(3)
396
+ expect(Date.parse('2012-08-15').quarter).to eq(3)
397
+ expect(Date.parse('2012-09-30').quarter).to eq(3)
398
+ expect(Date.parse('2012-10-01').quarter).to eq(4)
399
+ expect(Date.parse('2012-11-15').quarter).to eq(4)
400
+ expect(Date.parse('2012-12-31').quarter).to eq(4)
401
+ end
222
402
 
223
- it "should know about bimonths" do
224
- expect(Date.parse('2013-11-04').beginning_of_bimonth).to eq Date.parse('2013-11-01')
225
- expect(Date.parse('2013-11-04').end_of_bimonth).to eq Date.parse('2013-12-31')
226
- expect(Date.parse('2013-03-01')).to be_beginning_of_bimonth
227
- expect(Date.parse('2013-04-30')).to be_end_of_bimonth
228
- expect(Date.parse('2013-01-01')).to be_beginning_of_bimonth
229
- expect(Date.parse('2013-12-31')).to be_end_of_bimonth
230
- expect(Date.parse('2013-05-01')).to be_beginning_of_bimonth
231
- expect(Date.parse('2013-06-30')).to be_end_of_bimonth
232
- expect(Date.parse('2013-06-01')).to_not be_beginning_of_bimonth
233
- expect(Date.parse('2013-07-31')).to_not be_end_of_bimonth
234
- end
403
+ it "should know about years" do
404
+ expect(Date.parse('2013-01-01')).to be_beginning_of_year
405
+ expect(Date.parse('2013-12-31')).to be_end_of_year
406
+ expect(Date.parse('2013-04-01')).to_not be_beginning_of_year
407
+ expect(Date.parse('2013-12-30')).to_not be_end_of_year
408
+ end
235
409
 
236
- it "should know about months" do
237
- expect(Date.parse('2013-01-01')).to be_beginning_of_month
238
- expect(Date.parse('2013-12-31')).to be_end_of_month
239
- expect(Date.parse('2013-05-01')).to be_beginning_of_month
240
- expect(Date.parse('2013-07-31')).to be_end_of_month
241
- expect(Date.parse('2013-05-02')).to_not be_beginning_of_month
242
- expect(Date.parse('2013-07-30')).to_not be_end_of_month
243
- end
410
+ it "should know about quarters" do
411
+ expect(Date.parse('2013-01-01')).to be_beginning_of_quarter
412
+ expect(Date.parse('2013-12-31')).to be_end_of_quarter
413
+ expect(Date.parse('2013-04-01')).to be_beginning_of_quarter
414
+ expect(Date.parse('2013-06-30')).to be_end_of_quarter
415
+ expect(Date.parse('2013-05-01')).to_not be_beginning_of_quarter
416
+ expect(Date.parse('2013-07-31')).to_not be_end_of_quarter
417
+ end
244
418
 
245
- it "should know about semimonths" do
246
- expect(Date.parse('2013-11-24').beginning_of_semimonth).to eq Date.parse('2013-11-16')
247
- expect(Date.parse('2013-11-04').beginning_of_semimonth).to eq Date.parse('2013-11-01')
248
- expect(Date.parse('2013-11-04').end_of_semimonth).to eq Date.parse('2013-11-15')
249
- expect(Date.parse('2013-11-24').end_of_semimonth).to eq Date.parse('2013-11-30')
250
- expect(Date.parse('2013-03-01')).to be_beginning_of_semimonth
251
- expect(Date.parse('2013-03-16')).to be_beginning_of_semimonth
252
- expect(Date.parse('2013-04-15')).to be_end_of_semimonth
253
- expect(Date.parse('2013-04-30')).to be_end_of_semimonth
254
- end
419
+ it "should know about bimonths" do
420
+ expect(Date.parse('2013-11-04').beginning_of_bimonth).to eq Date.parse('2013-11-01')
421
+ expect(Date.parse('2013-11-04').end_of_bimonth).to eq Date.parse('2013-12-31')
422
+ expect(Date.parse('2013-03-01')).to be_beginning_of_bimonth
423
+ expect(Date.parse('2013-04-30')).to be_end_of_bimonth
424
+ expect(Date.parse('2013-01-01')).to be_beginning_of_bimonth
425
+ expect(Date.parse('2013-12-31')).to be_end_of_bimonth
426
+ expect(Date.parse('2013-05-01')).to be_beginning_of_bimonth
427
+ expect(Date.parse('2013-06-30')).to be_end_of_bimonth
428
+ expect(Date.parse('2013-06-01')).to_not be_beginning_of_bimonth
429
+ expect(Date.parse('2013-07-31')).to_not be_end_of_bimonth
430
+ end
255
431
 
256
- it "should know about biweeks" do
257
- expect(Date.parse('2013-11-07').beginning_of_biweek).to eq Date.parse('2013-11-04')
258
- expect(Date.parse('2013-11-07').end_of_biweek).to eq Date.parse('2013-11-17')
259
- expect(Date.parse('2013-03-11')).to be_beginning_of_biweek
260
- expect(Date.parse('2013-03-24')).to be_end_of_biweek
261
- end
432
+ it "should know about months" do
433
+ expect(Date.parse('2013-01-01')).to be_beginning_of_month
434
+ expect(Date.parse('2013-12-31')).to be_end_of_month
435
+ expect(Date.parse('2013-05-01')).to be_beginning_of_month
436
+ expect(Date.parse('2013-07-31')).to be_end_of_month
437
+ expect(Date.parse('2013-05-02')).to_not be_beginning_of_month
438
+ expect(Date.parse('2013-07-30')).to_not be_end_of_month
439
+ end
262
440
 
263
- it "should know about weeks" do
264
- expect(Date.parse('2013-11-04')).to be_beginning_of_week
265
- expect(Date.parse('2013-11-10')).to be_end_of_week
266
- expect(Date.parse('2013-12-02')).to be_beginning_of_week
267
- expect(Date.parse('2013-12-08')).to be_end_of_week
268
- expect(Date.parse('2013-10-13')).to_not be_beginning_of_week
269
- expect(Date.parse('2013-10-19')).to_not be_end_of_week
270
- end
441
+ it "should know about semimonths" do
442
+ expect(Date.parse('2013-11-24').beginning_of_semimonth).to eq Date.parse('2013-11-16')
443
+ expect(Date.parse('2013-11-04').beginning_of_semimonth).to eq Date.parse('2013-11-01')
444
+ expect(Date.parse('2013-11-04').end_of_semimonth).to eq Date.parse('2013-11-15')
445
+ expect(Date.parse('2013-11-24').end_of_semimonth).to eq Date.parse('2013-11-30')
446
+ expect(Date.parse('2013-03-01')).to be_beginning_of_semimonth
447
+ expect(Date.parse('2013-03-16')).to be_beginning_of_semimonth
448
+ expect(Date.parse('2013-04-15')).to be_end_of_semimonth
449
+ expect(Date.parse('2013-04-30')).to be_end_of_semimonth
450
+ end
271
451
 
272
- it "should know the beginning of chunks" do
273
- expect(Date.parse('2013-11-04').beginning_of_chunk(:year)).to eq Date.parse('2013-01-01')
274
- expect(Date.parse('2013-11-04').beginning_of_chunk(:quarter)).to eq Date.parse('2013-10-01')
275
- expect(Date.parse('2013-12-04').beginning_of_chunk(:bimonth)).to eq Date.parse('2013-11-01')
276
- expect(Date.parse('2013-11-04').beginning_of_chunk(:month)).to eq Date.parse('2013-11-01')
277
- expect(Date.parse('2013-11-04').beginning_of_chunk(:semimonth)).to eq Date.parse('2013-11-01')
278
- expect(Date.parse('2013-11-24').beginning_of_chunk(:semimonth)).to eq Date.parse('2013-11-16')
279
- expect(Date.parse('2013-11-08').beginning_of_chunk(:biweek)).to eq Date.parse('2013-11-04')
280
- expect(Date.parse('2013-11-08').beginning_of_chunk(:week)).to eq Date.parse('2013-11-04')
281
- expect {
282
- Date.parse('2013-11-04').beginning_of_chunk(:wek)
283
- }.to raise_error
284
- end
452
+ it "should know about biweeks" do
453
+ expect(Date.parse('2013-11-07').beginning_of_biweek).to eq Date.parse('2013-11-04')
454
+ expect(Date.parse('2013-11-07').end_of_biweek).to eq Date.parse('2013-11-17')
455
+ expect(Date.parse('2013-03-11')).to be_beginning_of_biweek
456
+ expect(Date.parse('2013-03-24')).to be_end_of_biweek
457
+ end
458
+
459
+ it "should know about weeks" do
460
+ expect(Date.parse('2013-11-04')).to be_beginning_of_week
461
+ expect(Date.parse('2013-11-10')).to be_end_of_week
462
+ expect(Date.parse('2013-12-02')).to be_beginning_of_week
463
+ expect(Date.parse('2013-12-08')).to be_end_of_week
464
+ expect(Date.parse('2013-10-13')).to_not be_beginning_of_week
465
+ expect(Date.parse('2013-10-19')).to_not be_end_of_week
466
+ end
467
+
468
+ it "should know the beginning of chunks" do
469
+ expect(Date.parse('2013-11-04').beginning_of_chunk(:year)).to eq Date.parse('2013-01-01')
470
+ expect(Date.parse('2013-11-04').beginning_of_chunk(:quarter)).to eq Date.parse('2013-10-01')
471
+ expect(Date.parse('2013-12-04').beginning_of_chunk(:bimonth)).to eq Date.parse('2013-11-01')
472
+ expect(Date.parse('2013-11-04').beginning_of_chunk(:month)).to eq Date.parse('2013-11-01')
473
+ expect(Date.parse('2013-11-04').beginning_of_chunk(:semimonth)).to eq Date.parse('2013-11-01')
474
+ expect(Date.parse('2013-11-24').beginning_of_chunk(:semimonth)).to eq Date.parse('2013-11-16')
475
+ expect(Date.parse('2013-11-08').beginning_of_chunk(:biweek)).to eq Date.parse('2013-11-04')
476
+ expect(Date.parse('2013-11-08').beginning_of_chunk(:week)).to eq Date.parse('2013-11-04')
477
+ expect {
478
+ Date.parse('2013-11-04').beginning_of_chunk(:wek)
479
+ }.to raise_error
480
+ end
481
+
482
+ it "should be able to add a chuck sym to itself" do
483
+ # Date.today is '2012-07-18'
484
+ expect(Date.today.add_chunk(:year)).to eq(Date.parse('2013-07-18'))
485
+ expect(Date.today.add_chunk(:quarter)).to eq(Date.parse('2012-10-18'))
486
+ expect(Date.today.add_chunk(:bimonth)).to eq(Date.parse('2012-09-18'))
487
+ expect(Date.today.add_chunk(:month)).to eq(Date.parse('2012-08-18'))
488
+ expect(Date.today.add_chunk(:semimonth)).to eq(Date.parse('2012-08-02'))
489
+ expect(Date.today.add_chunk(:biweek)).to eq(Date.parse('2012-08-01'))
490
+ expect(Date.today.add_chunk(:week)).to eq(Date.parse('2012-07-25'))
491
+ expect(Date.today.add_chunk(:day)).
492
+ to eq(Date.parse('2012-07-19'))
493
+ expect {
494
+ Date.today.add_chunk(:hour)
495
+ }.to raise_error ArgumentError
496
+ end
285
497
 
286
- it "should know the end of chunks" do
287
- expect(Date.parse('2013-07-04').end_of_chunk(:year)).to eq Date.parse('2013-12-31')
288
- expect(Date.parse('2013-07-04').end_of_chunk(:quarter)).to eq Date.parse('2013-09-30')
289
- expect(Date.parse('2013-12-04').end_of_chunk(:bimonth)).to eq Date.parse('2013-12-31')
290
- expect(Date.parse('2013-07-04').end_of_chunk(:month)).to eq Date.parse('2013-07-31')
291
- expect(Date.parse('2013-11-04').end_of_chunk(:semimonth)).to eq Date.parse('2013-11-15')
292
- expect(Date.parse('2013-11-24').end_of_chunk(:semimonth)).to eq Date.parse('2013-11-30')
293
- expect(Date.parse('2013-11-08').end_of_chunk(:biweek)).to eq Date.parse('2013-11-17')
294
- expect(Date.parse('2013-07-04').end_of_chunk(:week)).to eq Date.parse('2013-07-07')
295
- expect {
296
- Date.parse('2013-11-04').end_of_chunk(:wek)
297
- }.to raise_error
498
+ it "should know the end of chunks" do
499
+ expect(Date.parse('2013-07-04').end_of_chunk(:year)).to eq Date.parse('2013-12-31')
500
+ expect(Date.parse('2013-07-04').end_of_chunk(:quarter)).to eq Date.parse('2013-09-30')
501
+ expect(Date.parse('2013-12-04').end_of_chunk(:bimonth)).to eq Date.parse('2013-12-31')
502
+ expect(Date.parse('2013-07-04').end_of_chunk(:month)).to eq Date.parse('2013-07-31')
503
+ expect(Date.parse('2013-11-04').end_of_chunk(:semimonth)).to eq Date.parse('2013-11-15')
504
+ expect(Date.parse('2013-11-24').end_of_chunk(:semimonth)).to eq Date.parse('2013-11-30')
505
+ expect(Date.parse('2013-11-08').end_of_chunk(:biweek)).to eq Date.parse('2013-11-17')
506
+ expect(Date.parse('2013-07-04').end_of_chunk(:week)).to eq Date.parse('2013-07-07')
507
+ expect {
508
+ Date.parse('2013-11-04').end_of_chunk(:wek)
509
+ }.to raise_error
510
+ end
511
+
512
+ it "should know how to expand to chunk periods" do
513
+ expect(Date.parse('2013-07-04').expand_to_period(:year)).to eq Period.new('2013-01-01', '2013-12-31')
514
+ expect(Date.parse('2013-07-04').expand_to_period(:quarter)).to eq Period.new('2013-07-01', '2013-09-30')
515
+ expect(Date.parse('2013-07-04').expand_to_period(:bimonth)).to eq Period.new('2013-07-01', '2013-08-31')
516
+ expect(Date.parse('2013-07-04').expand_to_period(:month)).to eq Period.new('2013-07-01', '2013-07-31')
517
+ expect(Date.parse('2013-07-04').expand_to_period(:semimonth)).to eq Period.new('2013-07-01', '2013-07-15')
518
+ expect(Date.parse('2013-07-04').expand_to_period(:biweek)).to eq Period.new('2013-07-01', '2013-07-14')
519
+ expect(Date.parse('2013-07-04').expand_to_period(:week)).to eq Period.new('2013-07-01', '2013-07-07')
520
+ expect(Date.parse('2013-07-04').expand_to_period(:day)).to eq Period.new('2013-07-04', '2013-07-04')
521
+ end
522
+
523
+ it "should know if it's within 6 months of another date" do
524
+ # This uses Section 16's logic that one date is "within a
525
+ # period of less than six months" of another date only if it
526
+ # is within the date six months minus 2 days away from the
527
+ # current date.
528
+ expect(Date.parse('2014-01-12'))
529
+ .to be_within_6mos_of(Date.parse('2014-06-12'))
530
+ expect(Date.parse('2014-01-12'))
531
+ .not_to be_within_6mos_of(Date.parse('2014-07-12'))
532
+ expect(Date.parse('2014-01-12'))
533
+ .not_to be_within_6mos_of(Date.parse('2014-07-11'))
534
+ expect(Date.parse('2014-01-12'))
535
+ .to be_within_6mos_of(Date.parse('2014-07-10'))
536
+ end
298
537
  end
299
538
 
300
- it "should know how to expand to chunk periods" do
301
- expect(Date.parse('2013-07-04').expand_to_period(:year)).to eq Period.new('2013-01-01', '2013-12-31')
302
- expect(Date.parse('2013-07-04').expand_to_period(:quarter)).to eq Period.new('2013-07-01', '2013-09-30')
303
- expect(Date.parse('2013-07-04').expand_to_period(:bimonth)).to eq Period.new('2013-07-01', '2013-08-31')
304
- expect(Date.parse('2013-07-04').expand_to_period(:month)).to eq Period.new('2013-07-01', '2013-07-31')
305
- expect(Date.parse('2013-07-04').expand_to_period(:semimonth)).to eq Period.new('2013-07-01', '2013-07-15')
306
- expect(Date.parse('2013-07-04').expand_to_period(:biweek)).to eq Period.new('2013-07-01', '2013-07-14')
307
- expect(Date.parse('2013-07-04').expand_to_period(:week)).to eq Period.new('2013-07-01', '2013-07-07')
308
- expect(Date.parse('2013-07-04').expand_to_period(:day)).to eq Period.new('2013-07-04', '2013-07-04')
539
+ describe "holidays" do
540
+ it "should know Easter in its year" do
541
+ expect(Date.today.easter_this_year).to eq(Date.parse('2012-04-08'))
542
+ expect(Date.parse('2014-04-20').easter?).to be true
543
+ expect(Date.parse('2014-03-20').easter?).to be false
544
+ end
545
+
546
+ it "should know if its a federal holiday" do
547
+ # Got these from:
548
+ # http://www.opm.gov/policy-data-oversight/snow-dismissal-procedures/federal-holidays/
549
+
550
+ # For 2011:
551
+ # Friday, December 31, 2010 * New Year's Day
552
+ # Monday, January 17 Birthday of Martin Luther King, Jr.
553
+ # Monday, February 21 ** Washington's Birthday
554
+ # Monday, May 30 Memorial Day
555
+ # Monday, July 4 Independence Day
556
+ # Monday, September 5 Labor Day
557
+ # Monday, October 10 Columbus Day
558
+ # Friday, November 11 Veterans Day
559
+ # Thursday, November 24 Thanksgiving Day
560
+ # Tuesday, December 26 *** Christmas Day
561
+ expect(Date.parse('2010-12-31')).to be_fed_holiday
562
+ expect(Date.parse('2011-01-17')).to be_fed_holiday
563
+ expect(Date.parse('2011-02-21')).to be_fed_holiday
564
+ expect(Date.parse('2011-05-30')).to be_fed_holiday
565
+ expect(Date.parse('2011-07-04')).to be_fed_holiday
566
+ expect(Date.parse('2011-09-05')).to be_fed_holiday
567
+ expect(Date.parse('2011-10-10')).to be_fed_holiday
568
+ expect(Date.parse('2011-11-11')).to be_fed_holiday
569
+ expect(Date.parse('2011-11-24')).to be_fed_holiday
570
+ expect(Date.parse('2011-12-26')).to be_fed_holiday
571
+
572
+ # For 2014:
573
+ # Wednesday, January 1 New Year’s Day
574
+ # Monday, January 20 Birthday of Martin Luther King, Jr.
575
+ # Monday, February 17 Washington’s Birthday
576
+ # Monday, May 26 Memorial Day
577
+ # Friday, July 4 Independence Day
578
+ # Monday, September 1 Labor Day
579
+ # Monday, October 13 Columbus Day
580
+ # Tuesday, November 11 Veterans Day
581
+ # Thursday, November 27 Thanksgiving Day
582
+ # Thursday, December 25 Christmas Day
583
+ expect(Date.parse('2014-01-01')).to be_fed_holiday
584
+ expect(Date.parse('2014-01-20')).to be_fed_holiday
585
+ expect(Date.parse('2014-02-17')).to be_fed_holiday
586
+ expect(Date.parse('2014-05-26')).to be_fed_holiday
587
+ expect(Date.parse('2014-07-04')).to be_fed_holiday
588
+ expect(Date.parse('2014-09-01')).to be_fed_holiday
589
+ expect(Date.parse('2014-10-13')).to be_fed_holiday
590
+ expect(Date.parse('2014-11-11')).to be_fed_holiday
591
+ expect(Date.parse('2014-11-27')).to be_fed_holiday
592
+ expect(Date.parse('2014-12-25')).to be_fed_holiday
593
+ # Not holidays
594
+ expect(Date.parse('2014-02-14')).not_to be_fed_holiday
595
+ expect(Date.parse('2014-04-18')).not_to be_fed_holiday
596
+
597
+ # For 2017:
598
+ # Monday, January 2 New Year’s Day
599
+ # Monday, January 16 Birthday of Martin Luther King, Jr.
600
+ # Monday, February 20 Washington’s Birthday
601
+ # Monday, May 29 Memorial Day
602
+ # Tuesday, July 4 Independence Day
603
+ # Monday, September 4 Labor Day
604
+ # Monday, October 9 Columbus Day
605
+ # Friday, November 10 Veterans Day
606
+ # Thursday, November 23 Thanksgiving Day
607
+ # Monday, December 25 Christmas Day
608
+ expect(Date.parse('2017-01-02')).to be_fed_holiday
609
+ expect(Date.parse('2017-01-16')).to be_fed_holiday
610
+ expect(Date.parse('2017-02-20')).to be_fed_holiday
611
+ expect(Date.parse('2017-05-29')).to be_fed_holiday
612
+ expect(Date.parse('2017-07-04')).to be_fed_holiday
613
+ expect(Date.parse('2017-09-04')).to be_fed_holiday
614
+ expect(Date.parse('2017-10-09')).to be_fed_holiday
615
+ expect(Date.parse('2017-11-10')).to be_fed_holiday
616
+ expect(Date.parse('2017-11-23')).to be_fed_holiday
617
+ expect(Date.parse('2017-12-25')).to be_fed_holiday
618
+
619
+ # 2003 and 2008 had Christmas on Thur and this apparently makes
620
+ # the following Friday a holiday. I can't find any authority
621
+ # for this, but the government appeared to be shut down on these
622
+ # days.
623
+ expect(Date.parse('2003-12-26')).to be_fed_holiday
624
+ expect(Date.parse('2008-12-26')).to be_fed_holiday
625
+
626
+ # Some non-holidays
627
+ # New Year's Eve is /not/ a holiday unless on a weekend
628
+ # New Year's Eve on a Thursday
629
+ expect(Date.parse('2015-12-31')).not_to be_fed_holiday
630
+ # New Year's Eve on a Saturday
631
+ expect(Date.parse('2016-12-31')).to be_fed_holiday
632
+ # Monday
633
+ expect(Date.parse('2014-11-17')).not_to be_fed_holiday
634
+ # Tuesday
635
+ expect(Date.parse('2014-11-18')).not_to be_fed_holiday
636
+ # Wednesday
637
+ expect(Date.parse('2014-11-19')).not_to be_fed_holiday
638
+ # Thursday
639
+ expect(Date.parse('2014-11-20')).not_to be_fed_holiday
640
+ # Friday
641
+ expect(Date.parse('2014-11-21')).not_to be_fed_holiday
642
+
643
+ # Weekends are holidays, regardless
644
+ expect(Date.parse('2014-11-22')).to be_fed_holiday
645
+ expect(Date.parse('2014-11-23')).to be_fed_holiday
646
+ end
647
+
648
+ it "should know if its an NYSE holiday" do
649
+ ################# 2014 2015 2016
650
+ # New Year’s Day January 1 January 1 January 1
651
+ # Martin Luther King, Jr. Day January 20 January 19 January 18
652
+ # Washington’s Birthday February 17 February 16 February 15
653
+ # Good Friday April 18 April 3 March 25
654
+ # Memorial Day May 26 May 25 May 30
655
+ # Independence Day July 4 July 3 July 4
656
+ # Labor Day September 1 September 7 September 5
657
+ # Thanksgiving Day November 27 November 26 November 24
658
+ # Christmas Day December 25 December 25 December 26
659
+ expect(Date.parse('2014-01-01')).to be_nyse_holiday
660
+ expect(Date.parse('2014-01-20')).to be_nyse_holiday
661
+ expect(Date.parse('2014-02-17')).to be_nyse_holiday
662
+ expect(Date.parse('2014-04-18')).to be_nyse_holiday
663
+ expect(Date.parse('2014-05-26')).to be_nyse_holiday
664
+ expect(Date.parse('2014-07-04')).to be_nyse_holiday
665
+ expect(Date.parse('2014-09-01')).to be_nyse_holiday
666
+ expect(Date.parse('2014-10-13')).not_to be_nyse_holiday
667
+ expect(Date.parse('2014-11-11')).not_to be_nyse_holiday
668
+ expect(Date.parse('2014-11-27')).to be_nyse_holiday
669
+ expect(Date.parse('2014-12-25')).to be_nyse_holiday
670
+
671
+ expect(Date.parse('2015-01-01')).to be_nyse_holiday
672
+ expect(Date.parse('2015-01-19')).to be_nyse_holiday
673
+ expect(Date.parse('2015-02-16')).to be_nyse_holiday
674
+ expect(Date.parse('2015-04-03')).to be_nyse_holiday
675
+ expect(Date.parse('2015-05-25')).to be_nyse_holiday
676
+ expect(Date.parse('2015-07-03')).to be_nyse_holiday
677
+ expect(Date.parse('2015-09-07')).to be_nyse_holiday
678
+ expect(Date.parse('2015-10-13')).not_to be_nyse_holiday
679
+ expect(Date.parse('2015-11-11')).not_to be_nyse_holiday
680
+ expect(Date.parse('2015-11-26')).to be_nyse_holiday
681
+ expect(Date.parse('2015-12-25')).to be_nyse_holiday
682
+
683
+ expect(Date.parse('2016-01-01')).to be_nyse_holiday
684
+ expect(Date.parse('2016-01-18')).to be_nyse_holiday
685
+ expect(Date.parse('2016-02-15')).to be_nyse_holiday
686
+ expect(Date.parse('2016-03-25')).to be_nyse_holiday
687
+ expect(Date.parse('2016-05-30')).to be_nyse_holiday
688
+ expect(Date.parse('2016-07-04')).to be_nyse_holiday
689
+ expect(Date.parse('2016-09-05')).to be_nyse_holiday
690
+ expect(Date.parse('2016-10-13')).not_to be_nyse_holiday
691
+ expect(Date.parse('2016-11-11')).not_to be_nyse_holiday
692
+ expect(Date.parse('2016-11-26')).to be_nyse_holiday
693
+ expect(Date.parse('2016-12-26')).to be_nyse_holiday
694
+
695
+ # Some non-holidays
696
+ # Monday
697
+ expect(Date.parse('2014-11-17')).not_to be_nyse_holiday
698
+ # Tuesday
699
+ expect(Date.parse('2014-11-18')).not_to be_nyse_holiday
700
+ # Wednesday
701
+ expect(Date.parse('2014-11-19')).not_to be_nyse_holiday
702
+ # Thursday
703
+ expect(Date.parse('2014-11-20')).not_to be_nyse_holiday
704
+ # Friday
705
+ expect(Date.parse('2014-11-21')).not_to be_nyse_holiday
706
+
707
+ # Weekends are holidays, regardless
708
+ expect(Date.parse('2014-11-22')).to be_nyse_holiday
709
+ expect(Date.parse('2014-11-23')).to be_nyse_holiday
710
+ end
711
+
712
+ it "should know if it is a Federal workday" do
713
+ # Some holidays
714
+ expect(Date.parse('2017-02-20')).not_to be_fed_workday
715
+ expect(Date.parse('2017-05-29')).not_to be_fed_workday
716
+ expect(Date.parse('2017-07-04')).not_to be_fed_workday
717
+
718
+ # Some non-holidays
719
+ # Monday
720
+ expect(Date.parse('2014-11-17')).to be_fed_workday
721
+ # Tuesday
722
+ expect(Date.parse('2014-11-18')).to be_fed_workday
723
+ # Wednesday
724
+ expect(Date.parse('2014-11-19')).to be_fed_workday
725
+ # Thursday
726
+ expect(Date.parse('2014-11-20')).to be_fed_workday
727
+ # Friday
728
+ expect(Date.parse('2014-11-21')).to be_fed_workday
729
+
730
+ # Weekends are holidays, regardless
731
+ expect(Date.parse('2014-11-22')).not_to be_fed_workday
732
+ expect(Date.parse('2014-11-23')).not_to be_fed_workday
733
+ end
734
+
735
+ it "should know if it is an NYSE workday" do
736
+ # Some holidays
737
+ expect(Date.parse('2016-01-01')).not_to be_nyse_workday
738
+ expect(Date.parse('2016-01-18')).not_to be_nyse_workday
739
+ expect(Date.parse('2016-02-15')).not_to be_nyse_workday
740
+
741
+ # Some non-holidays
742
+ # Monday
743
+ expect(Date.parse('2014-11-17')).to be_nyse_workday
744
+ # Tuesday
745
+ expect(Date.parse('2014-11-18')).to be_nyse_workday
746
+ # Wednesday
747
+ expect(Date.parse('2014-11-19')).to be_nyse_workday
748
+ # Thursday
749
+ expect(Date.parse('2014-11-20')).to be_nyse_workday
750
+ # Friday
751
+ expect(Date.parse('2014-11-21')).to be_nyse_workday
752
+
753
+ # Weekends are holidays, regardless
754
+ expect(Date.parse('2014-11-22')).not_to be_nyse_workday
755
+ expect(Date.parse('2014-11-23')).not_to be_nyse_workday
756
+ end
757
+
758
+ it "should know the next federal workday" do
759
+ expect(Date.parse('2015-12-31').next_fed_workday)
760
+ .to eq Date.parse('2016-01-04')
761
+ expect(Date.parse('2016-04-20').next_fed_workday)
762
+ .to eq Date.parse('2016-04-21')
763
+ expect(Date.parse('2016-04-22').next_fed_workday)
764
+ .to eq Date.parse('2016-04-25')
765
+ end
766
+
767
+ it "should know the prior federal workday" do
768
+ expect(Date.parse('2016-01-04').prior_fed_workday)
769
+ .to eq Date.parse('2015-12-31')
770
+ expect(Date.parse('2016-04-21').prior_fed_workday)
771
+ .to eq Date.parse('2016-04-20')
772
+ expect(Date.parse('2016-04-25').prior_fed_workday)
773
+ .to eq Date.parse('2016-04-22')
774
+ end
775
+
776
+ it "should know the next NYSE workday" do
777
+ expect(Date.parse('2015-12-31').next_nyse_workday)
778
+ .to eq Date.parse('2016-01-04')
779
+ expect(Date.parse('2016-04-20').next_nyse_workday)
780
+ .to eq Date.parse('2016-04-21')
781
+ expect(Date.parse('2016-04-22').next_nyse_workday)
782
+ .to eq Date.parse('2016-04-25')
783
+ end
784
+
785
+ it "should know the prior NYSE workday" do
786
+ # The Monday after Easter; go to prior Thur since Good Friday
787
+ # is an NYSE holiday.
788
+ expect(Date.parse('2014-04-21').prior_nyse_workday)
789
+ .to eq Date.parse('2014-04-17')
790
+ expect(Date.parse('2016-01-04').prior_nyse_workday)
791
+ .to eq Date.parse('2015-12-31')
792
+ expect(Date.parse('2016-04-21').prior_nyse_workday)
793
+ .to eq Date.parse('2016-04-20')
794
+ expect(Date.parse('2016-04-25').prior_nyse_workday)
795
+ .to eq Date.parse('2016-04-22')
796
+ end
309
797
  end
310
798
  end
311
799
  end