datestamp,"Holiday name"
####
[vxp@vxp ~]$ ./zhopa.pl 20081231 mo
The full path is /home/vxp/holidays/mo.csv
Date passed to script: 20081231
Checking 20090101
20090101 is a day off, now will check 20090102
Checking 20090102
20090102 is a day off, now will check 20090103
Checking 20090103
20090103 is a day off, now will check 20090104
Checking 20090104
20090104 is a day off, now will check 20090105
Checking 20090105
20090105 is a day off, now will check 20090106
Checking 20090106
The next business day is: 20090106
[vxp@vxp ~]$
####
#!/usr/bin/perl
use Time::Local 'timelocal_nocheck';
use DateTime;
my $date_passed = shift;
my $zone = shift;
my $holiday_dir = "/home/vxp/holidays/";
$zone = lc($zone);
my $seconds_in_day = 86400;
#############################
# was a proper date given?
#############################
unless ($date_passed =~ /^\d{8}$/) {
print "The date must be in the yyyymmdd format. Example: 20090101\n";
exit(-1);
}
###############################################
# is the zone correct? was it even given?
###############################################
unless (($zone =~ /^ny$/) || ($zone =~ /^hk$/) || ($zone =~ /^mo$/) || ($zone =~ /^ln$/) || ($zone =~ /^tk$/ ) || ($zone =~ /^se$/ )) {
print "The acceptable zones are:\nNY\nHK\nMO\nLN\nTK\nSE\n";
exit(-1);
}
my $full_path_2_holiday_file = $holiday_dir . $zone . ".csv";
print "The full path is $full_path_2_holiday_file\n";
print "Date passed to script: $date_passed\n";
my $next_day = get_next_day($date_passed);
while (1) {
print "Checking $next_day\n";
$all_result = all_checks($next_day);
if ($all_result =~ /1/) {
print "The next business day is: $next_day\n";
exit(0);
} else {
print "$next_day is a day off, now will check ";
$next_day = get_next_day($next_day);
print "$next_day\n";
$all_result = all_checks($next_day);
}
}
sub all_checks {
##############################
# return codes are as follows
# 0 - dayoff
# 1 - workday
# -1 - error
#############################
my $date = shift || return(-1);
my $weekend_result = weekend_check($date);
my $holiday_result = holiday_check($date, $zone, $full_path_2_holiday_file);
if (($weekend_result =~ /1/) && ($holiday_result =~ /1/)) {
return(1);
} else {
return(0);
}
}
sub weekend_check {
##############################
# return codes are as follows
# 0 - weekend
# 1 - nonweekend
# -1 - error
#############################
my $date = shift || return(-1);
my $day_of_week = get_day($date);
unless (($day_of_week =~ /Monday/) || ($day_of_week =~ /Tuesday/) || ($day_of_week =~ /Wednesday/) || ($day_of_week =~ /Thursday/) || ($day_of_week =~ /Friday/) ) {
return(0);
} else {
return(1);
}
}
sub get_day {
#####################################
# return codes are as follows
# -1 - error
# otherwise, returns the day's name
#####################################
my $date = shift || return(-1);
my @weekday = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
my ($year,$mon,$mday) = $date =~ /(\d{4})(\d{2})(\d{2})/;
my $epochtime = timelocal_nocheck(0, 0, 0, $mday, $mon-1, $year);
my $day = (localtime($epochtime))[6];
return $weekday[$day];
}
sub get_next_day {
my $date = shift || return(-1);
my ($year,$mon,$mday) = $date =~ /(\d{4})(\d{2})(\d{2})/;
$dt = DateTime->new( year => $year,
month => $mon,
day => $mday,
hour => 13,
minute => 00,
second => 00,
nanosecond => 500000000,
time_zone => 'local',
);
# this is next day's epoch representation
$epoch_time = $dt->epoch + $seconds_in_day;
# converting epoch to human readable
$dt = DateTime->from_epoch( epoch => $epoch_time );
# mangle it to be in the right format
if ($dt =~ /(\d{4})-(\d{2})-(\d{2}).+/) {
$dt = $1 . $2 . $3
}
return $dt;
}
sub holiday_check {
##############################
# return codes are as follows
# 0 - holiday
# 1 - nonholiday
# -1 - error
#############################
my $date = shift || return(-1);
my $zone = shift || return(-1);
my $path = shift || return(-1);
open(HOLIDAYS, $path) or die "Couldn't open $path: $!\n";
while(defined($line = )) {
chomp($line);
my ($datestamp, $holiday_description) = split(/,/, $line);
$holidays{ $datestamp } = $holiday_description;
}
if ($zone =~ /ny/) {
if (exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
if ($zone =~ /hk/) {
if (exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
if ($zone =~ /mo/) {
if(exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
if ($zone =~ /ln/)
{
if(exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
if ($zone =~ /tk/) {
if(exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
if ($zone =~ /se/) {
if(exists($holidays{$date})) {
return(0);
} else {
return(1);
}
}
}