The solution worked great but I modified it to take a month parameter
to ease the consecutive use of generating the calendars following
January. i.e. first_sunday_of_calmonth(1,2005) and
first_sunday_of_calmonth(4,2006).
sub first_sunday_of_calmonth {
my $m = shift;
my $y = shift;
my $dow = strftime("%w", 0,0,0,1,$m-1,$y-1900);
my $time = timelocal(0,0,0,1,$m-1,$y-1900);
return $time - ($dow * 24 * 60 * 60);
}
A latter poster was correct, I was seeking the upper left-most box on a
calendar. I have posted below the finished product which was a simple
pager rotation script that generates a calendar in Excel format. It is
designed at this time only to handle 3 people as I have to fix the mod
(%) math to handle a variable number of people properly. If anyone
knows a good solution please let me know. Critiques welcome!
--schedule.pl--
#!/usr/bin/perl
###### List of People to be on rotation
# --users, -u = "jeff,john,jack" with the person working evening that
week covering the weekend
# --year, -y = "2008" for instance.
# You may need to set yout TZ environment variable if the script cannot
# determine your time zone from the system.
######
use Getopt::Long;
use Date::Manip;
use Spreadsheet::WriteExcel;
use Calendar::Functions;
use Date::Holidays::USFederal;
use POSIX qw/strftime/;
use Time::Local;
my @users = ();
$result = GetOptions ("users|u=s" => \@users,
"year|y=s" => \$year);
print "first sunday of week 1 is: ", ParseDate("sunday week 0
$year"),"\n";
@users = split(/,/,join(',',@users));
print @users;
#this would be used later in mod math to get things rotating properly
#but it fails miserable due to the addition later
$totalUsers=scalar(@users);
my $first = first_sunday_of_calmonth(1,$year);
$date=strftime("%m/%d/%Y", localtime($first));
print ("Initial Offset is $date\n");
#Make A SpreadSheet
my $workbook = Spreadsheet::WriteExcel->new("alpha-pager-$year.xls"); #
Step 1
#Build Formats
$fmtMonth=$workbook->add_format();
$fmtMonth->set_align('center');
$fmtMonth->set_align('Vcenter');
$fmtMonth->set_border(1);
$fmtMonth->set_bg_color('white');
$fmtMonth->set_font('Times New Roman');
$fmtMonth->set_size(24);
$fmtMonth->set_bold(1);
$fmtWeek=$workbook->add_format();
$fmtWeek->set_align('center');
$fmtWeek->set_align('Vcenter');
$fmtWeek->set_border(1);
$fmtWeek->set_bg_color('white');
$fmtWeek->set_font('Times New Roman');
$fmtWeek->set_size(14);
$fmtWeek->set_bold(1);
$fmtDate=$workbook->add_format();
$fmtDate->set_align('left');
$fmtDate->set_align('top');
$fmtDate->set_left(1);
$fmtDate->set_right(1);
$fmtDate->set_bg_color('white');
$fmtDate->set_font('Times New Roman');
$fmtDate->set_size(12);
$fmtDate->set_bold(1);
$fmtText=$workbook->add_format();
$fmtText->set_align('left');
$fmtText->set_align('top');
$fmtText->set_left(1);
$fmtText->set_right(1);
$fmtText->set_bg_color('white');
$fmtText->set_font('Arial');
$fmtText->set_size(10);
$fmtText->set_bold(0);
$fmtHoliday=$workbook->add_format();
$fmtHoliday->set_align('right');
$fmtHoliday->set_align('bottom');
$fmtHoliday->set_text_wrap(1);
$fmtHoliday->set_left(1);
$fmtHoliday->set_right(1);
$fmtHoliday->set_bottom(1);
$fmtHoliday->set_bg_color('white');
$fmtHoliday->set_font('Arial');
$fmtHoliday->set_color('Blue');
$fmtHoliday->set_size(8);
$fmtHoliday->set_bold(1);
$fmtDate2=$workbook->add_format();
$fmtDate2->set_align('left');
$fmtDate2->set_align('top');
$fmtDate2->set_left(1);
$fmtDate2->set_right(1);
$fmtDate2->set_bg_color('silver');
$fmtDate2->set_font('Times New Roman');
$fmtDate2->set_color('grey');
$fmtDate2->set_size(12);
$fmtDate2->set_bold(1);
$fmtText2=$workbook->add_format();
$fmtText2->set_align('left');
$fmtText2->set_align('top');
$fmtText2->set_left(1);
$fmtText2->set_right(1);
$fmtText2->set_bg_color('silver');
$fmtText2->set_font('Arial');
$fmtText2->set_color('grey');
$fmtText2->set_size(10);
$fmtText2->set_bold(0);
$fmtHoliday2=$workbook->add_format();
$fmtHoliday2->set_align('right');
$fmtHoliday2->set_align('bottom');
$fmtHoliday2->set_left(1);
$fmtHoliday2->set_right(1);
$fmtHoliday2->set_bottom(1);
$fmtHoliday2->set_bg_color('silver');
$fmtHoliday2->set_font('Arial');
$fmtHoliday2->set_color('plum');
$fmtHoliday2->set_size(8);
$fmtHoliday2->set_text_wrap(1);
$fmtHoliday2->set_bold(1);
@week=(
UnixDate(DateCalc($date,"+0 days"),"%A"),
UnixDate(DateCalc($date,"+1 days"),"%A"),
UnixDate(DateCalc($date,"+2 days"),"%A"),
UnixDate(DateCalc($date,"+3 days"),"%A"),
UnixDate(DateCalc($date,"+4 days"),"%A"),
UnixDate(DateCalc($date,"+5 days"),"%A"),
UnixDate(DateCalc($date,"+6 days"),"%A"),
);
for($month=1;$month<13;$month++)
{
$first = first_sunday_of_calmonth($month,$year);
$date=strftime("%m/%d/%Y", localtime($first));
$workbook->add_worksheet((UnixDate("$month/1/$year","%B")));
$workbook->sheets($month-1)->merge_range(0,0,0,6,UnixDate("$month/1/$year","%B")."
- $year",$fmtMonth);
$workbook->sheets($month-1)->set_column('A:A', 15);
$workbook->sheets($month-1)->set_column('B:B', 15);
$workbook->sheets($month-1)->set_column('C:C', 15);
$workbook->sheets($month-1)->set_column('D

', 15);
$workbook->sheets($month-1)->set_column('E:E', 15);
$workbook->sheets($month-1)->set_column('F:F', 15);
$workbook->sheets($month-1)->set_column('G:G', 15);
for($dow=0;$dow<7;$dow++){
$workbook->sheets($month-1)->write(1,$dow,dotw($dow),$fmtWeek);
}
#Render the Calendar Entries
for($row=2;$row < 30;$row+=5)
{
for($cols=0;$cols<7;$cols++)
{
#define the Roles, this is where mod math does
if not just three
$sunday=$users[($row)%$totalUsers];
$saturday=$users[($row+2)%$totalUsers];
$weekday=$users[($row+1)%$totalUsers];
$weeknight=$users[($row+2)%$totalUsers];
if (UnixDate($date,"%m") == $month) {
$workbook->sheets($month-1)->write($row,$cols,UnixDate($date,"%d"),$fmtDate);
$workbook->sheets($month-1)->write_blank($row+1,$cols,$fmtDate);
SWITCH: {
$cols==0 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Primary:
$sunday",$fmtText);
$workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
last;
};
$cols==6 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Primary:
$saturday",$fmtText);
$workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
last;
};
$cols!=6 || $cols!=0 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Days:
$weekday",$fmtText);
$workbook->sheets($month-1)->write($row+3,$cols,"Evenings:
$weeknight",$fmtText);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
last;
}
} #END OF SWITCH
} else {
$workbook->sheets($month-1)->write($row,$cols,UnixDate($date,"%d"),$fmtDate2);
$workbook->sheets($month-1)->write_blank($row+1,$cols,$fmtDate2);
SWITCH: {
$cols==0 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Primary:
$sunday",$fmtText2);
$workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText2);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
last;
};
$cols==6 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Primary:
$saturday",$fmtText2);
$workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText2);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
last;
};
$cols!=6 || $cols!=0 and do {
$workbook->sheets($month-1)->write($row+2,$cols,"Days:
$weekday",$fmtText2);
$workbook->sheets($month-1)->write($row+3,$cols,"Evenings:
$weeknight",$fmtText2);
$workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
last;
}
} #END OF SWITCH
}
$date=DateCalc($date,"+1 day");
}
if(UnixDate($date,"%m") > $month) {last;}
};
#Set Up The Printer Settings
$workbook->sheets($month-1)->center_horizontally();
$workbook->sheets($month-1)->center_vertically();
$workbook->sheets($month-1)->set_paper(1);
$workbook->sheets($month-1)->set_margins(.6);
$workbook->sheets($month-1)->set_landscape();
$workbook->sheets($month-1)->print_area(0,0,$row+4, $cols-1)
}
$workbook->close();
sub holidayCheck {
my $t = shift;
my $y = UnixDate($t,"%Y");
my $m = UnixDate($t,"%m");
my $d = UnixDate($t,"%d");
my $checkDate = "$m/$d/$y";
print "My CheckDate= $checkDate\n";
SWITCH: {
$checkDate eq "01/02/$y" and do {return "New Year's Day";};
$checkDate eq "01/16/$y" and do {return "Martin Luther King, Jr.
Day";};
$checkDate eq "02/20/$y" and do {return "Presidents' Day";};
$checkDate eq "05/29/$y" and do {return "Memorial Day";};
$checkDate eq "07/04/$y" and do {return "Independence Day";};
$checkDate eq "09/04/$y" and do {return "Labor Day";};
$checkDate eq "10/09/$y" and do {return "Columbus Day";};
$checkDate eq "11/11/$y" and do {return "Veterans' Day";};
$checkDate eq "11/23/$y" and do {return "Thanksgiving Day";};
$checkDate eq "12/25/$y" and do {return "Christmas Day";};
} #END SELECT
}
sub first_sunday_of_calmonth {
my $m = shift;
my $y = shift;
my $dow = strftime("%w", 0,0,0,1,$m-1,$y-1900);
my $time = timelocal(0,0,0,1,$m-1,$y-1900);
return $time - ($dow * 24 * 60 * 60);
}
--End Schedule--