File Coverage

blib/lib/Date/Holidays/US.pm
Criterion Covered Total %
statement 48 60 80.0
branch 54 66 81.8
condition 226 312 72.4
subroutine 8 8 100.0
pod 4 4 100.0
total 340 450 75.5


line stmt bran cond sub pod time code
1             package Date::Holidays::US;
2 7     7   428944 use strict;
  7         51  
  7         170  
3 7     7   26 use warnings;
  7         13  
  7         156  
4 7     7   29 use base qw{Exporter};
  7         9  
  7         862  
5 7     7   2857 use POSIX; #strftime to calculate wday
  7         37088  
  7         29  
6              
7             our @EXPORT_OK = qw(is_holiday holidays is_us_holiday us_holidays);
8              
9             our $VERSION = '0.01';
10              
11             =head1 NAME
12              
13             Date::Holidays::US - Date::Holidays Adapter for US Federal holidays
14              
15             =head1 SYNOPSIS
16              
17             use Date::Holidays::US qw{is_holiday};
18             my $holiday_name = is_holiday($year, $month, $day);
19              
20             =head1 DESCRIPTION
21              
22             Date::Holidays Adapter for US Federal holidays back to 1880 with updates from 2022.
23              
24             =head1 METHODS
25              
26             =head2 is_holiday
27              
28             my $holiday_name = Date::Holidays::US::is_holiday($year, $month, $day);
29             print "Holiday: $holiday_name\n";
30              
31             =cut
32              
33             sub is_holiday {
34 381     381 1 913 my $year = shift;
35 381         465 my $month = shift;
36 381         428 my $day = shift;
37 381         9636 my $wday = POSIX::strftime(qq{%w}, 0, 0, 0, $day, $month-1, $year-1900); #12:00 am
38              
39             #5 U.S. Code § 6103 - Holidays
40             #The history of federal holidays in the United States dates back to June 28, 1870
41 381 100 66     18467 if ($year > 1870 and $month == 1 and $day == 1) {
    50 100        
    100 66        
    100 100        
    50 66        
    50 100        
    100 100        
    50 66        
    100 100        
    100 66        
    100 100        
    100 100        
    50 66        
    100 100        
    100 100        
    100 66        
    100 66        
    50 66        
    50 33        
    50 100        
    50 66        
    100 100        
    50 100        
    100 66        
    100 66        
    100 33        
    50 100        
    100 66        
    100 66        
    100 66        
    100 100        
    50 100        
      100        
      100        
      100        
      100        
      100        
      100        
      66        
      100        
      66        
      66        
      100        
      66        
      100        
      100        
      66        
      66        
      66        
      66        
      100        
      100        
      100        
      100        
      33        
      33        
      33        
      0        
      33        
      33        
      33        
      33        
      33        
      33        
      0        
      66        
      66        
      66        
      33        
      66        
      66        
      66        
      33        
      33        
      33        
      0        
      66        
      66        
      66        
      33        
      33        
      66        
      100        
      100        
      66        
      100        
      66        
      100        
      66        
      66        
      100        
      66        
      100        
      66        
      100        
      100        
      66        
      100        
      66        
      100        
      100        
      66        
      100        
      66        
42 12         52 return q{New Year's Day}; #January 1
43             } elsif ($year > 1870 and $month == 1 and $day == 2 and $wday == 1) {
44 0         0 return q{New Year's Day Observed}; #Monday afer January 1
45              
46             #observed for the first time on January 20, 1986. - Pub.L. 98–399, 98 Stat. 1475, enacted November 2, 1983
47             } elsif ($year >= 1986 and $month == 1 and $day >= 15 and $day <= 21 and $wday == 1) {
48 8         32 return 'Birthday of Martin Luther King, Jr.' #the third Monday in January
49              
50             #Inauguration Day - Really only DC and few
51             } elsif ($year >= 1965 and $month == 1 and $day == 20 and $year % 4 == 1) {
52 1         5 return'Inauguration Day' #January 20 of each fourth year after 1965
53             } elsif ($year >= 1965 and $month == 1 and $day == 21 and $year % 4 == 1 and $wday == 1) {
54 0         0 return'Inauguration Day Observed' #When January 20 ... falls on Sunday, the next succeeding day ... observance
55              
56             # Washington's Birthday was celebrated on February 22 from 1879 until 1970.
57             # in 1968 the Uniform Monday Holiday Act moved it to the third Monday in February
58             # The Act was signed into law on June 1, 1968, and took effect on January 1, 1971.
59             } elsif ($year >= 1879 and $year < 1971 and $month == 2 and $day == 22) {
60 0         0 return q{Washington's Birthday}; #February 22 from 1879 until 1970
61             } elsif ($year >= 1971 and $month == 2 and $day >= 15 and $day <= 21 and $wday == 1) {
62 8         82 return q{Washington's Birthday}; #the third Monday in February
63              
64             # Memorial Day/Decoration Day
65             } elsif ($year >= 1888 and $year < 1971 and $month == 5 and $day == 30) {
66 0         0 return 'Decoration Day'; #May 30 #TODO: observed?
67             } elsif ($year >= 1971 and $month == 5 and $day >= 25 and $day <= 31 and $wday == 1) {
68 8         27 return 'Memorial Day'; #the last Monday in May
69              
70             #The day was first recognized as a federal holiday in June 2021, when President
71             #Joe Biden signed the Juneteenth National Independence Day Act into law.
72             } elsif ($year >= 2021 and $month == 6 and $day == 18 and $wday == 5) {
73 1         4 return 'Juneteenth National Independence Day Observed'; #Friday before June 19
74             } elsif ($year >= 2021 and $month == 6 and $day == 19) {
75 7         24 return 'Juneteenth National Independence Day'; #June 19
76             } elsif ($year >= 2021 and $month == 6 and $day == 20 and $wday == 1) {
77 4         9 return 'Juneteenth National Independence Day Observed'; #Monday afer June 19
78              
79             #Independence Day
80              
81             } elsif ($year >= 1870 and $month == 7 and $day == 3 and $wday == 5) {
82 0         0 return 'Independence Day Observed'; #Friday before July 4
83             } elsif ($year >= 1870 and $month == 7 and $day == 4) {
84 7         23 return 'Independence Day'; #July 4
85             } elsif ($year >= 1870 and $month == 7 and $day == 5 and $wday == 1) {
86 1         4 return 'Independence Day Observed'; #Monday afer July 4
87              
88             ## Labor Day
89             # By 1894, thirty U.S. states were already officially celebrating Labor Day. In that year,
90             # Congress passed a bill recognizing the first Monday of September as Labor Day and making
91             # it an official federal holiday. President Grover Cleveland signed the bill into law on
92             # June 28.[15][4] The federal law, however, only made it a holiday for federal workers.
93              
94             } elsif ($year >= 1894 and $month == 9 and $day >= 1 and $day <= 7 and $wday == 1) {
95 8         26 return 'Labor Day'; #the first Monday in September
96              
97             ##Columbus Day
98             #Uniform Monday Holiday Act
99             } elsif ($year >= 1971 and $month == 10 and $day >= 8 and $day <= 14 and $wday == 1) {
100 8         71 return 'Columbus Day'; #the second Monday in October
101              
102             ##Veterans Day (>1954)/Armistice Day (<1954)
103             #November 11 (1938 to 1970 and >1978)
104             #fourth Monday in October (1971 to 1977)
105              
106             } elsif ($year >= 1938 and $year < 1954 and $month == 11 and $day == 10 and $wday == 5) {
107 0         0 return 'Armistice Day Observed'; #Friday before November 11
108             } elsif ($year >= 1938 and $year < 1954 and $month == 11 and $day == 11) {
109 0         0 return 'Armistice Day'; #November 11
110             } elsif ($year >= 1938 and $year < 1954 and $month == 11 and $day == 12 and $wday == 1) {
111 0         0 return 'Armistice Day Observed'; #Monday afer November 11
112              
113             } elsif ($year >= 1954 and $year < 1971 and $month == 11 and $day == 10 and $wday == 5) {
114 0         0 return 'Veterans Day Observed'; #Friday before November 11
115             } elsif ($year >= 1954 and $year < 1971 and $month == 11 and $day == 11) {
116 1         5 return 'Veterans Day'; #November 11
117             } elsif ($year >= 1954 and $year < 1971 and $month == 11 and $day == 12 and $wday == 1) {
118 0         0 return 'Veterans Day Observed'; #Monday afer November 11
119              
120             } elsif ($year >= 1971 and $year < 1978 and $month == 10 and $day >= 22 and $day <= 28 and $wday == 1) {
121 7         36 return 'Veterans Day'; #fourth Monday in October
122              
123             } elsif ($year >= 1978 and $month == 11 and $day == 10 and $wday == 5) {
124 1         9 return 'Veterans Day Observed'; #Friday before November 11
125             } elsif ($year >= 1978 and $month == 11 and $day == 11) {
126 17         86 return 'Veterans Day'; #November 11
127             } elsif ($year >= 1978 and $month == 11 and $day == 12 and $wday == 1) {
128 0         0 return 'Veterans Day Observed'; #Monday afer November 11
129              
130             ##Thanksgiving Day
131             } elsif ($year >= 1870 and $month == 11 and $day >= 22 and $day <= 28 and $wday == 4) {
132 8         28 return 'Thanksgiving Day'; #the fourth Thursday in November.
133              
134             ##Christmas Day
135             } elsif ($year >= 1870 and $month == 12 and $day == 24 and $wday == 5) {
136 1         4 return 'Christmas Day Observed'; #Friday before December 25
137             } elsif ($year >= 1870 and $month == 12 and $day == 25) {
138 7         25 return 'Christmas Day'; #December 25
139             } elsif ($year >= 1870 and $month == 12 and $day == 26 and $wday == 1) {
140 4         14 return 'Christmas Day Observed'; #Monday afer December 25
141              
142             } elsif ($year >= 1870 and $month == 12 and $day == 31 and $wday == 5) {
143 0         0 return q{New Year's Day Observed}; #Friday before January 1
144              
145             } else {
146 262         664 return undef;
147             }
148             }
149              
150             =head2 is_us_holiday
151              
152             =cut
153              
154 4     4 1 904 sub is_us_holiday {return is_holiday(@_)};
155              
156             =head2 holidays
157              
158             =cut
159              
160             sub holidays {
161 5     5 1 11 my $year = shift;
162 5         9 my %holidays = ();
163             #All possible dates that could be a holiday
164 5         62 my @dates = qw{
165             0101 0102
166             0115 0116 0117 0118 0119 0120 0121
167             0222
168             0215 0216 0217 0218 0219 0220 0221
169             0525 0526 0527 0528 0529 0530 0531
170             0618 0619 0620
171             0703 0704 0705
172             0901 0902 0903 0904 0905 0906
173             1007 1008 1009 1010 1011 1012 1013
174             1110 1111 1112
175             1022 1023 1024 1025 1026 1027 1028
176             1122 1123 1124 1125 1126 1127 1128
177             1224 1225 1226
178             1231
179             };
180 5         9 foreach my $date (@dates) {
181 320         1414 my ($month, $day) = $date =~ m/\A(..)(..)\Z/;
182 320         586 my $name = is_holiday($year, $month, $day);
183 320 100       716 $holidays{$date} = $name if $name;
184             }
185 5         42 return \%holidays;
186             }
187              
188             =head2 us_holidays
189              
190             =cut
191              
192 2     2 1 6 sub us_holidays {return holidays(@_)};
193              
194             =head1 SEE ALSO
195              
196             L, L
197              
198             =head1 AUTHOR
199              
200             Michael R. Davis, MRDVT
201              
202             =head1 COPYRIGHT AND LICENSE
203              
204             Copyright (C) 2022 by Michael R. Davis
205              
206             MIT License
207              
208             =cut
209              
210             1;