Date-Holidays-NYSE
view release on metacpan or search on metacpan
lib/Date/Holidays/NYSE.pm view on Meta::CPAN
package Date::Holidays::NYSE;
use strict;
use warnings;
use base qw{Exporter};
use POSIX (); #strftime to calculate wday
use Date::Calc 5.0 (); #to calculate Easter and thus Good Friday
our @EXPORT_OK = qw(is_holiday holidays is_nyse_holiday nyse_holidays);
our $VERSION = '0.04';
=head1 NAME
Date::Holidays::NYSE - Date::Holidays Adapter for New York Stock Exchange (NYSE) holidays
=head1 SYNOPSIS
use Date::Holidays::NYSE qw{is_holiday};
my $holiday_name = is_holiday($year, $month, $day);
=head1 DESCRIPTION
Date::Holidays Adapter for New York Stock Exchange (NYSE) holidays
Per https://www.nyse.com/markets/hours-calendars these are the NYSE holidays.
New Years Day (not observed on 12/31)
Martin Luther King, Jr. Day
Washington's Birthday
Good Friday (falls between March 20 and April 23)
Memorial Day
Juneteenth National Independence Day (first observed in 2022)
Independence Day
Labor Day
Thanksgiving Day
Christmas Day
=head1 METHODS
=head2 is_holiday
Returns a holiday name or undef given three arguments (year, month, day).
my ($year, $month, $day) = (2023, 4, 7);
use Date::Holidays::NYSE qw{is_holiday};
my $holiday_name = is_holiday($year, $month, $day);
if (defined $holiday_name) {
print "Holiday: $holiday_name\n"; #Good Friday
} else {
print "Not a NYSE Holiday\n";
}
=cut
sub is_holiday {
my $year = shift;
my $month = shift;
my $day = shift;
my $wday = POSIX::strftime(qq{%w}, 0, 0, 0, $day, $month-1, $year-1900); #12:00 am #0=Sun, 1=Mon, 6=Sat
my $is_good_friday = 0;
if ($wday == 5 and (($month == 3 and $day >= 20) or ($month == 4 and $day <= 23))) { #Check Fridays in March and April for Good Friday
# Good Friday is the Friday before Easter Sunday.
# Easter can happen on any day from March 22 to April 25.
# thus Good Friday can happen on any day from March 20 to April 23.
my ($year_easter , $month_easter , $day_easter ) = Date::Calc::Easter_Sunday($year);
my ($year_good_friday, $month_good_friday, $day_good_friday) = Date::Calc::Add_Delta_Days($year_easter, $month_easter, $day_easter, -2);
if ($year == $year_good_friday and $month == $month_good_friday and $day == $day_good_friday) {
$is_good_friday = 1;
}
}
#Ref: https://www.nyse.com/markets/hours-calendars
#Ref: https://web.archive.org/web/20101203013357/http://www.nyse.com/about/newsevents/1176373643795.html
#Friday 12/31 - New Years' Day (January 1) in 2011 falls on a Saturday. The rules of the applicable exchanges state that when a holiday falls on a Saturday, we observe the preceding Friday unless the Friday is the end of a monthly or yearly account...
if ($month == 1 and $day == 1 and $wday >= 1 and $wday <= 5) { #New Year's Day on a Weekday
return q{New Year's Day};
} elsif ($month == 1 and $day == 2 and $wday == 1) { #Monday after New Year's Day
return q{New Year's Day Observed};
} elsif ($month == 1 and $day >= 15 and $day <= 21 and $wday == 1) { #Third Monday in January
return 'Martin Luther King, Jr. Day';
} elsif ($month == 2 and $day >= 15 and $day <= 21 and $wday == 1) { #Third Monday in February
return q{Washington's Birthday};
} elsif ($is_good_friday) { #Good Friday between March 20 and April 23
return 'Good Friday';
} elsif ($month == 5 and $day >= 25 and $day <= 31 and $wday == 1) { #Last Monday in May
return 'Memorial Day';
} elsif ($year >= 2022 and $month == 6 and $day == 18 and $wday == 5) { #Juneteenth on a Friday
return 'Juneteenth National Independence Day Observed';
} elsif ($year >= 2022 and $month == 6 and $day == 19 and $wday >= 1 and $wday <= 5) { #Juneteenth on a weekday
return 'Juneteenth National Independence Day';
} elsif ($year >= 2022 and $month == 6 and $day == 20 and $wday == 1) { #Juneteenth on a Monday
return 'Juneteenth National Independence Day Observed';
} elsif ($month == 7 and $day == 3 and $wday == 5) { #Friday before July 4
return 'Independence Day Observed';
} elsif ($month == 7 and $day == 4 and $wday >= 1 and $wday <= 5) { #July 4 on a weekday
return 'Independence Day';
} elsif ($month == 7 and $day == 5 and $wday == 1) { #Monday after July 4
return 'Independence Day Observed';
} elsif ($month == 9 and $day >= 1 and $day <= 7 and $wday == 1) { #First Monday in September
return 'Labor Day';
} elsif ($month == 11 and $day >= 22 and $day <= 28 and $wday == 4) { #Fourth Thursday in November.
return 'Thanksgiving Day';
} elsif ($month == 12 and $day == 24 and $wday == 5) { #Friday before December 25
return 'Christmas Day Observed';
} elsif ($month == 12 and $day == 25 and $wday >= 1 and $wday <= 5) { #December 25 on a weekday
return 'Christmas Day';
} elsif ($month == 12 and $day == 26 and $wday == 1) { #Monday after December 25
return 'Christmas Day Observed';
} elsif ($year == 2025 and $month == 1 and $day == 9) { #Day of Mourning for Jimmy Carter
return 'Day of Mourning for President Jimmy Carter';
} else {
return undef;
}
}
=head2 is_nyse_holiday
Wrapper around is_holiday function per the API specification. See L<Date::Holidays/is_holiday1>
=cut
sub is_nyse_holiday {return is_holiday(@_)};
=head2 holidays
Returns a hash reference containing all of the holidays in the specified year. The keys for the returned hash reference are the dates where 2-digit month and 2-digit day are concatenated.
use Date::Holidays::US qw{holidays};
my $year = 2023;
my $holidays_href = holidays($year);
foreach my $key (sort keys %$holidays_href) { #e.g. "0101", "0619","0704"
my ($month, $day) = $key =~ m/\A([0-9]{2})([0-9]{2})\Z/;
( run in 1.097 second using v1.01-cache-2.11-cpan-364913b4093 )