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.
- checksums.yaml +4 -4
- data/fat_core.gemspec +1 -0
- data/lib/fat_core/date.rb +178 -186
- data/lib/fat_core/period.rb +1 -1
- data/lib/fat_core/version.rb +1 -1
- data/spec/lib/date_spec.rb +628 -140
- data/spec/lib/period_spec.rb +17 -0
- data/spec/spec_helper.rb +4 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94d627be45140f03aae806d7efd270587f82fdd0
|
4
|
+
data.tar.gz: 6fd13f11a973858fb854d22e53c2cb74555e27fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b82eef90d9fc99462877615c30880f51207de6d28a1cd3530a6b997677111d54996b9d302972b869f9c6225137803ec3eba2a0aa0f09a76f612da0a478bb75af
|
7
|
+
data.tar.gz: 6f284960e4c93e57daaa8b28ea34595b8a80fea89dc01234dc56b0c2722610fbedc25130fd0e58c21bc8ac3aaddcbd7ecf7933b09a5cda736bdb059cfb8f80e0
|
data/fat_core.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_development_dependency 'simplecov'
|
21
22
|
spec.add_development_dependency "bundler", "~> 1.5"
|
22
23
|
spec.add_development_dependency "rake"
|
23
24
|
spec.add_development_dependency "rspec"
|
data/lib/fat_core/date.rb
CHANGED
@@ -164,34 +164,60 @@ class Date
|
|
164
164
|
end # !> previous definition of length was here
|
165
165
|
end
|
166
166
|
|
167
|
-
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
def weekday?
|
172
|
-
!weekend?
|
173
|
-
end
|
174
|
-
|
167
|
+
# Predecessor of self. Allows Date to work as a countable element
|
168
|
+
# of a Range.
|
175
169
|
def pred
|
176
170
|
self - 1.day
|
177
171
|
end
|
178
172
|
|
173
|
+
# Successor of self. Allows Date to work as a countable element
|
174
|
+
# of a Range.
|
179
175
|
def succ
|
180
176
|
self + 1.day
|
181
177
|
end
|
182
178
|
|
179
|
+
# Format as an ISO string.
|
183
180
|
def iso
|
184
181
|
strftime("%Y-%m-%d")
|
185
182
|
end
|
186
183
|
|
184
|
+
# Format date to TeX documents as ISO strings
|
185
|
+
def tex_quote
|
186
|
+
iso
|
187
|
+
end
|
188
|
+
|
189
|
+
# Format as an all-numeric string, i.e. 'YYYYMMDD'
|
190
|
+
def num
|
191
|
+
strftime("%Y%m%d")
|
192
|
+
end
|
193
|
+
|
194
|
+
# Format as an inactive Org date (see emacs org-mode)
|
187
195
|
def org
|
188
196
|
strftime("[%Y-%m-%d %a]")
|
189
197
|
end
|
190
198
|
|
199
|
+
# Format as an English string
|
191
200
|
def eng
|
192
201
|
strftime("%B %e, %Y")
|
193
202
|
end
|
194
203
|
|
204
|
+
# Format date in MM/DD/YYYY form, as typical for the short American
|
205
|
+
# form.
|
206
|
+
def american
|
207
|
+
strftime "%-m/%-d/%Y"
|
208
|
+
end
|
209
|
+
|
210
|
+
# Does self fall on a weekend?
|
211
|
+
def weekend?
|
212
|
+
saturday? || sunday?
|
213
|
+
end
|
214
|
+
|
215
|
+
# Does self fall on a weekday?
|
216
|
+
def weekday?
|
217
|
+
!weekend?
|
218
|
+
end
|
219
|
+
|
220
|
+
# Self's calendar quarter: 1, 2, 3, or 4
|
195
221
|
def quarter
|
196
222
|
case month
|
197
223
|
when (1..3)
|
@@ -205,6 +231,10 @@ class Date
|
|
205
231
|
end
|
206
232
|
end
|
207
233
|
|
234
|
+
# The date that is the first day of the bimonth in which self
|
235
|
+
# falls. A 'bimonth' is a two-month calendar period beginning on the
|
236
|
+
# first day of the odd-numbered months. E.g., 2014-01-01 to
|
237
|
+
# 2014-02-28 is the first bimonth of 2014.
|
208
238
|
def beginning_of_bimonth
|
209
239
|
if month % 2 == 1
|
210
240
|
beginning_of_month
|
@@ -213,6 +243,10 @@ class Date
|
|
213
243
|
end
|
214
244
|
end
|
215
245
|
|
246
|
+
# The date that is the last day of the bimonth in which self falls.
|
247
|
+
# A 'bimonth' is a two-month calendar period beginning on the first
|
248
|
+
# day of the odd-numbered months. E.g., 2014-01-01 to 2014-02-28 is
|
249
|
+
# the first bimonth of 2014.
|
216
250
|
def end_of_bimonth
|
217
251
|
if month % 2 == 1
|
218
252
|
(self + 1.month).end_of_month
|
@@ -221,6 +255,10 @@ class Date
|
|
221
255
|
end
|
222
256
|
end
|
223
257
|
|
258
|
+
# The date that is the first day of the semimonth in which self
|
259
|
+
# falls. A semimonth is a calendar period beginning on the 1st or
|
260
|
+
# 16th of each month and ending on the 15th or last day of the month
|
261
|
+
# respectively. So each year has exactly 24 semimonths.
|
224
262
|
def beginning_of_semimonth
|
225
263
|
if day >= 16
|
226
264
|
Date.new(year, month, 16)
|
@@ -229,6 +267,10 @@ class Date
|
|
229
267
|
end
|
230
268
|
end
|
231
269
|
|
270
|
+
# The date that is the last day of the semimonth in which self
|
271
|
+
# falls. A semimonth is a calendar period beginning on the 1st or
|
272
|
+
# 16th of each month and ending on the 15th or last day of the month
|
273
|
+
# respectively. So each year has exactly 24 semimonths.
|
232
274
|
def end_of_semimonth
|
233
275
|
if day <= 15
|
234
276
|
Date.new(year, month, 15)
|
@@ -237,8 +279,8 @@ class Date
|
|
237
279
|
end
|
238
280
|
end
|
239
281
|
|
240
|
-
# Note: we use a
|
241
|
-
# commercial week counting assumes a
|
282
|
+
# Note: we use a Monday start of the week in the next two methods because
|
283
|
+
# commercial week counting assumes a Monday start.
|
242
284
|
def beginning_of_biweek
|
243
285
|
if cweek % 2 == 1
|
244
286
|
beginning_of_week(:monday)
|
@@ -313,11 +355,6 @@ class Date
|
|
313
355
|
self.end_of_week == self
|
314
356
|
end
|
315
357
|
|
316
|
-
# Format date in MM/DD/YYYY form
|
317
|
-
def american
|
318
|
-
strftime "%-m/%-d/%Y"
|
319
|
-
end
|
320
|
-
|
321
358
|
def expand_to_period(sym)
|
322
359
|
require 'fat_core/period'
|
323
360
|
Period.new(beginning_of_chunk(sym), end_of_chunk(sym))
|
@@ -342,7 +379,7 @@ class Date
|
|
342
379
|
when :day
|
343
380
|
self + 1.days
|
344
381
|
else
|
345
|
-
raise
|
382
|
+
raise ArgumentError, "add_chunk unknown chunk: '#{chunk}'"
|
346
383
|
end
|
347
384
|
end
|
348
385
|
|
@@ -365,7 +402,7 @@ class Date
|
|
365
402
|
when :day
|
366
403
|
self
|
367
404
|
else
|
368
|
-
raise
|
405
|
+
raise ArgumentError, "unknown chunk sym: '#{sym}'"
|
369
406
|
end
|
370
407
|
end
|
371
408
|
|
@@ -393,20 +430,37 @@ class Date
|
|
393
430
|
end
|
394
431
|
|
395
432
|
# Holidays decreed by executive order
|
396
|
-
|
433
|
+
# See http://www.whitehouse.gov/the-press-office/2012/12/21/
|
434
|
+
# executive-order-closing-executive-departments-and-agencies-federal-gover
|
435
|
+
FED_DECREED_HOLIDAYS =
|
397
436
|
[
|
398
437
|
Date.parse('2012-12-24')
|
399
438
|
]
|
400
439
|
|
401
440
|
def self.days_in_month(y, m)
|
441
|
+
if m < 1 || m > 12
|
442
|
+
raise ArgumentError, "illegal month number"
|
443
|
+
end
|
402
444
|
days = Time::COMMON_YEAR_DAYS_IN_MONTH[m]
|
403
|
-
|
404
|
-
|
445
|
+
if m == 2
|
446
|
+
Date.new(y, m, 1).leap? ? 29 : 28
|
447
|
+
else
|
448
|
+
days
|
449
|
+
end
|
405
450
|
end
|
406
451
|
|
407
452
|
def self.nth_wday_in_year_month(n, wday, year, month)
|
408
453
|
# Return the nth weekday in the given month
|
409
454
|
# If n is negative, count from last day of month
|
455
|
+
wday = wday.to_i
|
456
|
+
if wday < 0 || wday > 6
|
457
|
+
raise ArgumentError, "illegal weekday number"
|
458
|
+
end
|
459
|
+
month = month.to_i
|
460
|
+
if month < 1 || month > 12
|
461
|
+
raise ArgumentError, "illegal month number"
|
462
|
+
end
|
463
|
+
n = n.to_i
|
410
464
|
if n > 0
|
411
465
|
# Set d to the 1st wday in month
|
412
466
|
d = Date.new(year, month, 1)
|
@@ -419,12 +473,11 @@ class Date
|
|
419
473
|
d += 7
|
420
474
|
nd += 1
|
421
475
|
end
|
422
|
-
|
476
|
+
d
|
423
477
|
elsif n < 0
|
424
478
|
n = -n
|
425
479
|
# Set d to the last wday in month
|
426
|
-
d = Date.new(year, month,
|
427
|
-
Date.last_day_in_year_month(year, month))
|
480
|
+
d = Date.new(year, month, 1).end_of_month
|
428
481
|
while d.wday != wday;
|
429
482
|
d -= 1
|
430
483
|
end
|
@@ -434,36 +487,22 @@ class Date
|
|
434
487
|
d -= 7
|
435
488
|
nd += 1
|
436
489
|
end
|
437
|
-
|
490
|
+
d
|
438
491
|
else
|
439
492
|
raise ArgumentError,
|
440
493
|
'Arg 1 to nth_wday_in_month_year cannot be zero'
|
441
494
|
end
|
442
495
|
end
|
443
496
|
|
444
|
-
def
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
31, # Mar
|
450
|
-
30, # Apr
|
451
|
-
31, # May
|
452
|
-
30, # Jun
|
453
|
-
31, # Jul
|
454
|
-
31, # Aug
|
455
|
-
30, # Sep
|
456
|
-
31, # Oct
|
457
|
-
30, # Nov
|
458
|
-
31, # Dec
|
459
|
-
]
|
460
|
-
days[2] = 29 if Date.new(year, month, 1).leap?
|
461
|
-
days[month % 12]
|
497
|
+
def within_6mos_of?(d)
|
498
|
+
# Date 6 calendar months before self
|
499
|
+
start_date = self - 6.months + 2.days
|
500
|
+
end_date = self + 6.months - 2.days
|
501
|
+
(start_date..end_date).cover?(d)
|
462
502
|
end
|
463
503
|
|
464
|
-
def
|
465
|
-
|
466
|
-
y = self.year
|
504
|
+
def self.easter(year)
|
505
|
+
y = year
|
467
506
|
a = y % 19
|
468
507
|
b, c = y.divmod(100)
|
469
508
|
d, e = b.divmod(4)
|
@@ -474,47 +513,45 @@ class Date
|
|
474
513
|
l = (32 + 2*e + 2*i - h - k) % 7
|
475
514
|
m = (a + 11*h + 22*l) / 451
|
476
515
|
n, p = (h + l - 7*m + 114).divmod(31)
|
477
|
-
|
516
|
+
Date.new(y, n, p + 1)
|
517
|
+
end
|
518
|
+
|
519
|
+
def easter_this_year
|
520
|
+
# Return the date of Easter in self's year
|
521
|
+
Date.easter(self.year)
|
478
522
|
end
|
479
523
|
|
480
524
|
def easter?
|
481
525
|
# Am I Easter?
|
482
|
-
|
483
|
-
return false unless [3, 4].include?(self.mon)
|
484
|
-
return self == self.easter_this_year
|
526
|
+
self == self.easter_this_year
|
485
527
|
end
|
486
528
|
|
487
529
|
def nth_wday_in_month?(n, wday, month)
|
488
530
|
# Is self the nth weekday in the given month of its year?
|
489
531
|
# If n is negative, count from last day of month
|
490
|
-
|
491
|
-
return false
|
492
|
-
elsif self.mon != month
|
493
|
-
return false
|
494
|
-
else
|
495
|
-
return self == Date.nth_wday_in_year_month(n, wday, self.year, month)
|
496
|
-
end
|
532
|
+
self == Date.nth_wday_in_year_month(n, wday, self.year, month)
|
497
533
|
end
|
498
534
|
|
535
|
+
#######################################################
|
536
|
+
# Calculations for Federal holidays
|
537
|
+
# 5 USC 6103
|
538
|
+
#######################################################
|
499
539
|
def fed_fixed_holiday?
|
500
540
|
# Fixed-date holidays on weekdays
|
501
541
|
if self.mon == 1 && self.mday == 1
|
502
542
|
# New Years (January 1),
|
503
|
-
|
543
|
+
true
|
504
544
|
elsif self.mon == 7 && self.mday == 4
|
505
545
|
# Independence Day (July 4),
|
506
|
-
|
546
|
+
true
|
507
547
|
elsif self.mon == 11 && self.mday == 11
|
508
548
|
# Veterans Day (November 11),
|
509
|
-
|
549
|
+
true
|
510
550
|
elsif self.mon == 12 && self.mday == 25
|
511
551
|
# Christmas (December 25), and
|
512
|
-
|
513
|
-
elsif self.mon == 12 && self.mday == 31
|
514
|
-
# New Year's Eve (December 31)
|
515
|
-
return true;
|
552
|
+
true
|
516
553
|
else
|
517
|
-
|
554
|
+
false
|
518
555
|
end
|
519
556
|
end
|
520
557
|
|
@@ -524,66 +561,58 @@ class Date
|
|
524
561
|
|
525
562
|
# No moveable feasts in certain months
|
526
563
|
if [ 3, 4, 6, 7, 8, 12 ].include?(self.month)
|
527
|
-
|
564
|
+
false
|
528
565
|
elsif self.wday == 1
|
566
|
+
moveable_mondays = []
|
529
567
|
# MLK's Birthday (Third Monday in Jan)
|
530
|
-
|
568
|
+
moveable_mondays << self.nth_wday_in_month?(3, 1, 1)
|
531
569
|
# Washington's Birthday (Third Monday in Feb)
|
532
|
-
|
570
|
+
moveable_mondays << self.nth_wday_in_month?(3, 1, 2)
|
533
571
|
# Memorial Day (Last Monday in May)
|
534
|
-
|
572
|
+
moveable_mondays << self.nth_wday_in_month?(-1, 1, 5)
|
535
573
|
# Labor Day (First Monday in Sep)
|
536
|
-
|
574
|
+
moveable_mondays << self.nth_wday_in_month?(1, 1, 9)
|
537
575
|
# Columbus Day (Second Monday in Oct)
|
538
|
-
|
576
|
+
moveable_mondays << self.nth_wday_in_month?(2, 1, 10)
|
539
577
|
# Other Mondays
|
540
|
-
|
578
|
+
moveable_mondays.any?
|
541
579
|
elsif self.wday == 4
|
542
580
|
# Thanksgiving Day (Fourth Thur in Nov)
|
543
|
-
|
544
|
-
return self.nth_wday_in_month?(4, 4, 11)
|
581
|
+
self.nth_wday_in_month?(4, 4, 11)
|
545
582
|
else
|
546
|
-
|
583
|
+
false
|
547
584
|
end
|
548
585
|
end
|
549
586
|
|
550
587
|
def fed_holiday?
|
551
|
-
if FED_DECLARED_HOLIDAYS.include?(self)
|
552
|
-
return true
|
553
|
-
end
|
554
|
-
|
555
588
|
# All Saturdays and Sundays are "holidays"
|
556
|
-
if self.weekend?
|
557
|
-
|
558
|
-
# Is self a fixed holiday
|
559
|
-
return true if self.fed_fixed_holiday?
|
589
|
+
return true if self.weekend?
|
560
590
|
|
561
|
-
#
|
562
|
-
|
563
|
-
if self.wday == 5
|
564
|
-
td = self + 1
|
565
|
-
return true if td.fed_fixed_holiday?
|
566
|
-
end
|
591
|
+
# Some days are holidays by executive decree
|
592
|
+
return true if FED_DECREED_HOLIDAYS.include?(self)
|
567
593
|
|
568
|
-
#
|
569
|
-
|
570
|
-
if self.wday == 1
|
571
|
-
td = self - 1
|
572
|
-
return true if td.fed_fixed_holiday?
|
573
|
-
end
|
594
|
+
# Is self a fixed holiday
|
595
|
+
return true if (self.fed_fixed_holiday? || self.fed_moveable_feast?)
|
574
596
|
|
575
|
-
# If Christmas falls on a Thursday, apparently, the Friday after is
|
576
|
-
# treated as a holiday as well. See 2003, 2008, for example.
|
577
597
|
if self.wday == 5 and self.month == 12 and self.day == 26
|
578
|
-
|
598
|
+
# If Christmas falls on a Thursday, apparently, the Friday after is
|
599
|
+
# treated as a holiday as well. See 2003, 2008, for example.
|
600
|
+
true
|
601
|
+
elsif self.wday == 5
|
602
|
+
# A Friday is a holiday if a fixed-date holiday
|
603
|
+
# would fall on the following Saturday
|
604
|
+
(self + 1).fed_fixed_holiday? || (self + 1).fed_moveable_feast?
|
605
|
+
elsif self.wday == 1
|
606
|
+
# A Monday is a holiday if a fixed-date holiday
|
607
|
+
# would fall on the preceding Sunday
|
608
|
+
(self - 1).fed_fixed_holiday? || (self - 1).fed_moveable_feast?
|
609
|
+
else
|
610
|
+
false
|
579
611
|
end
|
580
|
-
|
581
|
-
# It's last chance is if its a movable feast
|
582
|
-
return self.fed_moveable_feast?;
|
583
612
|
end
|
584
613
|
|
585
614
|
#######################################################
|
586
|
-
#
|
615
|
+
# Calculations for NYSE holidays
|
587
616
|
# Rule 51 and supplementary material
|
588
617
|
#######################################################
|
589
618
|
|
@@ -605,15 +634,15 @@ class Date
|
|
605
634
|
# Fixed-date holidays
|
606
635
|
if self.mon == 1 && self.mday == 1
|
607
636
|
# New Years (January 1),
|
608
|
-
|
637
|
+
true
|
609
638
|
elsif self.mon == 7 && self.mday == 4
|
610
639
|
# Independence Day (July 4),
|
611
|
-
|
640
|
+
true
|
612
641
|
elsif self.mon == 12 && self.mday == 25
|
613
642
|
# Christmas (December 25), and
|
614
|
-
|
643
|
+
true
|
615
644
|
else
|
616
|
-
|
645
|
+
false
|
617
646
|
end
|
618
647
|
end
|
619
648
|
|
@@ -623,7 +652,7 @@ class Date
|
|
623
652
|
|
624
653
|
# No moveable feasts in certain months
|
625
654
|
if [ 6, 7, 8, 10, 12 ].include?(self.month)
|
626
|
-
|
655
|
+
false
|
627
656
|
elsif self.wday == 1
|
628
657
|
# MLK's Birthday (Third Monday in Jan)
|
629
658
|
return true if self.nth_wday_in_month?(3, 1, 1)
|
@@ -634,17 +663,15 @@ class Date
|
|
634
663
|
# Labor Day (First Monday in Sep)
|
635
664
|
return true if self.nth_wday_in_month?(1, 1, 9)
|
636
665
|
# Other Mondays
|
637
|
-
|
666
|
+
false
|
638
667
|
elsif self.wday == 4
|
639
668
|
# Thanksgiving Day (Fourth Thur in Nov)
|
640
|
-
|
641
|
-
return self.nth_wday_in_month?(4, 4, 11)
|
669
|
+
self.nth_wday_in_month?(4, 4, 11)
|
642
670
|
elsif self.wday == 5
|
643
671
|
# Good Friday, the Friday before Easter
|
644
|
-
|
645
|
-
return td.easter?
|
672
|
+
(self + 2).easter?
|
646
673
|
else
|
647
|
-
|
674
|
+
false
|
648
675
|
end
|
649
676
|
end
|
650
677
|
|
@@ -653,105 +680,70 @@ class Date
|
|
653
680
|
return true if self.weekend?
|
654
681
|
|
655
682
|
# Is self a fixed holiday
|
656
|
-
return true if self.nyse_fixed_holiday?
|
683
|
+
return true if self.nyse_fixed_holiday? || self.nyse_moveable_feast?
|
657
684
|
|
658
|
-
# A Friday is a holiday if a fixed-date holiday
|
659
|
-
# would fall on the following Saturday
|
660
685
|
if self.wday == 5
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
686
|
+
# A Friday is a holiday if a fixed-date holiday
|
687
|
+
# would fall on the following Saturday
|
688
|
+
(self + 1).nyse_fixed_holiday? || (self + 1).nyse_moveable_feast?
|
689
|
+
elsif self.wday == 1
|
690
|
+
# A Monday is a holiday if a fixed-date holiday
|
691
|
+
# would fall on the preceding Sunday
|
692
|
+
(self - 1).nyse_fixed_holiday? || (self - 1).nyse_moveable_feast?
|
693
|
+
else
|
694
|
+
false
|
670
695
|
end
|
671
|
-
|
672
|
-
# It's last chance is if its a movable feast
|
673
|
-
return self.nyse_moveable_feast?;
|
674
696
|
end
|
675
697
|
|
676
698
|
def fed_workday?
|
677
|
-
|
699
|
+
!self.fed_holiday?
|
678
700
|
end
|
679
701
|
|
680
702
|
def nyse_workday?
|
681
|
-
|
682
|
-
end
|
683
|
-
|
684
|
-
def next_fed_workday
|
685
|
-
result = self + 1
|
686
|
-
while result.fed_holiday?
|
687
|
-
result += 1;
|
688
|
-
end
|
689
|
-
return result
|
703
|
+
!self.nyse_holiday?
|
690
704
|
end
|
691
705
|
|
692
706
|
def add_fed_business_days(n)
|
693
707
|
d = self.dup
|
694
|
-
if n
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
708
|
+
return d if n == 0
|
709
|
+
incr = n < 0 ? -1 : 1
|
710
|
+
n = n.abs
|
711
|
+
while n > 0
|
712
|
+
d += incr
|
713
|
+
if d.fed_workday?
|
714
|
+
n -= 1
|
715
|
+
end
|
716
|
+
end
|
699
717
|
d
|
700
718
|
end
|
701
719
|
|
702
|
-
def
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
return result
|
720
|
+
def next_fed_workday
|
721
|
+
self.add_fed_business_days(1)
|
722
|
+
end
|
723
|
+
|
724
|
+
def prior_fed_workday
|
725
|
+
self.add_fed_business_days(-1)
|
709
726
|
end
|
710
727
|
|
711
728
|
def add_nyse_business_days(n)
|
712
729
|
d = self.dup
|
713
|
-
if n
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
730
|
+
return d if n == 0
|
731
|
+
incr = n < 0 ? -1 : 1
|
732
|
+
n = n.abs
|
733
|
+
while n > 0
|
734
|
+
d += incr
|
735
|
+
if d.nyse_workday?
|
736
|
+
n -= 1
|
737
|
+
end
|
738
|
+
end
|
718
739
|
d
|
719
740
|
end
|
720
741
|
|
721
|
-
def
|
722
|
-
|
723
|
-
while result.fed_holiday?
|
724
|
-
result -= 1;
|
725
|
-
end
|
726
|
-
return result
|
742
|
+
def next_nyse_workday
|
743
|
+
self.add_nyse_business_days(1)
|
727
744
|
end
|
728
745
|
|
729
746
|
def prior_nyse_workday
|
730
|
-
|
731
|
-
result -= 1
|
732
|
-
while result.nyse_holiday?
|
733
|
-
result -= 1;
|
734
|
-
end
|
735
|
-
return result
|
736
|
-
end
|
737
|
-
|
738
|
-
def iso
|
739
|
-
strftime("%Y-%m-%d")
|
740
|
-
end
|
741
|
-
|
742
|
-
def num
|
743
|
-
strftime("%Y%m%d")
|
744
|
-
end
|
745
|
-
|
746
|
-
def within_6mos_of?(d)
|
747
|
-
# Date 6 calendar months before self
|
748
|
-
start_date = self - 6.months + 2.days
|
749
|
-
end_date = self + 6.months - 2.days
|
750
|
-
(start_date..end_date).cover?(d)
|
751
|
-
end
|
752
|
-
|
753
|
-
# Allow erb documents can directly interpolate dates
|
754
|
-
def tex_quote
|
755
|
-
iso
|
747
|
+
self.add_nyse_business_days(-1)
|
756
748
|
end
|
757
749
|
end
|