Created
February 16, 2012 23:58
-
-
Save chansen/1848964 to your computer and use it in GitHub Desktop.
US § 6103. HOLIDAYS (Federal)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
do 'us_federal_holidays.pl'; | |
# Test cases extracted from <http://www.opm.gov/Operating_Status_Schedules/fedhol/Index.asp> | |
my @tests = ( | |
[ 1997, '1997-01-01', '1997-01-20', '1997-02-17', '1997-05-26', '1997-07-04', | |
'1997-09-01', '1997-10-13', '1997-11-11', '1997-11-27', '1997-12-25' ], | |
[ 1998, '1998-01-01', '1998-01-19', '1998-02-16', '1998-05-25', '1998-07-03', | |
'1998-09-07', '1998-10-12', '1998-11-11', '1998-11-26', '1998-12-25' ], | |
[ 1999, '1999-01-01', '1999-01-18', '1999-02-15', '1999-05-31', '1999-07-05', | |
'1999-09-06', '1999-10-11', '1999-11-11', '1999-11-25', '1999-12-24' ], | |
[ 2000, '1999-12-31', '2000-01-17', '2000-02-21', '2000-05-29', '2000-07-04', | |
'2000-09-04', '2000-10-09', '2000-11-10', '2000-11-23', '2000-12-25' ], | |
[ 2001, '2001-01-01', '2001-01-15', '2001-02-19', '2001-05-28', '2001-07-04', | |
'2001-09-03', '2001-10-08', '2001-11-12', '2001-11-22', '2001-12-25' ], | |
[ 2002, '2002-01-01', '2002-01-21', '2002-02-18', '2002-05-27', '2002-07-04', | |
'2002-09-02', '2002-10-14', '2002-11-11', '2002-11-28', '2002-12-25' ], | |
[ 2003, '2003-01-01', '2003-01-20', '2003-02-17', '2003-05-26', '2003-07-04', | |
'2003-09-01', '2003-10-13', '2003-11-11', '2003-11-27', '2003-12-25' ], | |
[ 2004, '2004-01-01', '2004-01-19', '2004-02-16', '2004-05-31', '2004-07-05', | |
'2004-09-06', '2004-10-11', '2004-11-11', '2004-11-25', '2004-12-24' ], | |
[ 2005, '2004-12-31', '2005-01-17', '2005-02-21', '2005-05-30', '2005-07-04', | |
'2005-09-05', '2005-10-10', '2005-11-11', '2005-11-24', '2005-12-26' ], | |
[ 2006, '2006-01-02', '2006-01-16', '2006-02-20', '2006-05-29', '2006-07-04', | |
'2006-09-04', '2006-10-09', '2006-11-10', '2006-11-23', '2006-12-25' ], | |
[ 2007, '2007-01-01', '2007-01-15', '2007-02-19', '2007-05-28', '2007-07-04', | |
'2007-09-03', '2007-10-08', '2007-11-12', '2007-11-22', '2007-12-25' ], | |
[ 2008, '2008-01-01', '2008-01-21', '2008-02-18', '2008-05-26', '2008-07-04', | |
'2008-09-01', '2008-10-13', '2008-11-11', '2008-11-27', '2008-12-25' ], | |
[ 2009, '2009-01-01', '2009-01-19', '2009-02-16', '2009-05-25', '2009-07-03', | |
'2009-09-07', '2009-10-12', '2009-11-11', '2009-11-26', '2009-12-25' ], | |
[ 2010, '2010-01-01', '2010-01-18', '2010-02-15', '2010-05-31', '2010-07-05', | |
'2010-09-06', '2010-10-11', '2010-11-11', '2010-11-25', '2010-12-24' ], | |
[ 2011, '2010-12-31', '2011-01-17', '2011-02-21', '2011-05-30', '2011-07-04', | |
'2011-09-05', '2011-10-10', '2011-11-11', '2011-11-24', '2011-12-26' ], | |
[ 2012, '2012-01-02', '2012-01-16', '2012-02-20', '2012-05-28', '2012-07-04', | |
'2012-09-03', '2012-10-08', '2012-11-12', '2012-11-22', '2012-12-25' ], | |
[ 2013, '2013-01-01', '2013-01-21', '2013-02-18', '2013-05-27', '2013-07-04', | |
'2013-09-02', '2013-10-14', '2013-11-11', '2013-11-28', '2013-12-25' ], | |
[ 2014, '2014-01-01', '2014-01-20', '2014-02-17', '2014-05-26', '2014-07-04', | |
'2014-09-01', '2014-10-13', '2014-11-11', '2014-11-27', '2014-12-25' ], | |
[ 2015, '2015-01-01', '2015-01-19', '2015-02-16', '2015-05-25', '2015-07-03', | |
'2015-09-07', '2015-10-12', '2015-11-11', '2015-11-26', '2015-12-25' ], | |
[ 2016, '2016-01-01', '2016-01-18', '2016-02-15', '2016-05-30', '2016-07-04', | |
'2016-09-05', '2016-10-10', '2016-11-11', '2016-11-24', '2016-12-26' ], | |
[ 2017, '2017-01-02', '2017-01-16', '2017-02-20', '2017-05-29', '2017-07-04', | |
'2017-09-04', '2017-10-09', '2017-11-10', '2017-11-23', '2017-12-25' ], | |
[ 2018, '2018-01-01', '2018-01-15', '2018-02-19', '2018-05-28', '2018-07-04', | |
'2018-09-03', '2018-10-08', '2018-11-12', '2018-11-22', '2018-12-25' ], | |
[ 2019, '2019-01-01', '2019-01-21', '2019-02-18', '2019-05-27', '2019-07-04', | |
'2019-09-02', '2019-10-14', '2019-11-11', '2019-11-28', '2019-12-25' ], | |
[ 2020, '2020-01-01', '2020-01-20', '2020-02-17', '2020-05-25', '2020-07-03', | |
'2020-09-07', '2020-10-12', '2020-11-11', '2020-11-26', '2020-12-25' ], | |
); | |
use Test::More tests => 24; | |
foreach my $test (@tests) { | |
my ($year, @dates) = @$test; | |
my $exp = join ', ', @dates; | |
my $got = join ', ', map { $_->ymd } calculate_federal_holidays($year); | |
is($got, $exp, "expected federal holidays for year $year"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use DateTime qw[]; | |
sub _ymd { | |
my ($y, $m, $d) = @_; | |
return DateTime->new(year => $y, month => $m, day => $d); | |
} | |
# Federal law 5 USC § 6103 - HOLIDAYS | |
# http://www.law.cornell.edu/uscode/text/5/6103 | |
sub calculate_federal_holidays { | |
@_ == 1 || Carp::croak(q/Usage: calculate_federal_holiday($year)/); | |
my ($year) = @_; | |
my @dates = (); | |
# New Year's Day | |
push @dates, _ymd($year, 1, 1); | |
# Birthday of Martin Luther King, Jr. | |
push @dates, do { | |
# Third Monday in January | |
my $date = _ymd($year, 1, 1); | |
$date->add(days => 2*7 + (1 - $date->day_of_week) % 7); | |
}; | |
# Inauguration Day | |
# § 6103. HOLIDAYS (c) | |
# push @dates, _ymd($year, 1, 20) | |
# if $year % 4 == 1 && $dates[-1]->day != 20; # 1969, 1997, 2025 ... | |
# Washington's Birthday | |
push @dates, do { | |
# Third Monday in February | |
my $date = _ymd($year, 2, 1); | |
$date->add(days => 2*7 + (1 - $date->day_of_week) % 7); | |
}; | |
# Memorial Day | |
push @dates, do { | |
# Last Monday in May | |
my $date = _ymd($year, 5, 31); | |
$date->subtract(days => ($date->day_of_week - 1) % 7); | |
}; | |
# Independence Day | |
push @dates, _ymd($year, 7, 4); | |
# Labor Day | |
push @dates, do { | |
# First Monday in September | |
my $date = _ymd($year, 9, 1); | |
$date->add(days => (1 - $date->day_of_week) % 7); | |
}; | |
# Columbus Day | |
push @dates, do { | |
# Second Monday in October | |
my $date = _ymd($year, 10, 1); | |
$date->add(days => 1*7 + (1 - $date->day_of_week) % 7); | |
}; | |
# Veterans Day | |
push @dates, _ymd($year, 11, 11); | |
# Thanksgiving Day | |
push @dates, do { | |
# Fourth Thursday in November | |
my $date = _ymd($year, 11, 1); | |
$date->add(days => 3*7 + (4 - $date->day_of_week) % 7); | |
}; | |
# Christmas Day | |
push @dates, _ymd($year, 12, 25); | |
# § 6103. HOLIDAYS (b) | |
foreach my $date (@dates) { | |
$date->add(days => ($date->day_of_week == 6 ? -1 : +1)) | |
if $date->day_of_week > 5; | |
} | |
return @dates; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment