#! /usr/local/bin/perl
# -------------------------------
# a simple html-based calendar
# doug steinwand -- dzs@iname.com
# october 14, 1997
# -------------------------------
# Path and name for the data file:
#
$calfile="cal_sched.txt";
# Date format, select one of the following:
# 1 = month/day/year
# 2 = day/month/year
# 3 = year/month/day
#
$datefmt=1;
# The text used for the names of the months
@monthnames=("January","February","March","April",
"May","June","July","August","September",
"October","November","December");
# colors
$BACKGROUND="#ccccff"; # light blue
$CALBG= "#ffffff"; # white
$NOTINMONTH="#aaaaaa"; # gray
$TODAY= "#ffffcc"; # light yellow
$WEEKCOLOR= "#88eeee"; # light cyan
$SELECTED= "#ffaaaa"; # red
$EVENT= "#ddffdd"; # light green
# array for the days of the week.
@daynames=("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
# this hash holds the events. the key is the julian
# date and the value is the text for the event
my %events;
MAIN: {
# spit out http and html headers
print "content-type: text/html\n\n",
"
Calendar",
"\n";
# load calendar of events from disk
loadcalfile();
# which date to display
$date=$ENV{'QUERY_STRING'} || juliantoday();
# show the calendar for the given date
showonemonthcalendar($date, 1);
# show the day's events
showdaysevents($date);
# that's all
exit 0;
}
# displays a one-month calendar
# -----------------------------
# input: julian_date, enable_day_links
# output: prints calendar
#
# if enable_day_links, will display links for each day
#
sub showonemonthcalendar {
my($jul)=shift;
my($links)=shift;
my($year,$month,$day,$jstart,$jend,$jtoday,$cols,$i);
# convert the julian date
($year,$month,$day)=fromjulian($jul);
# find the julian start and end values for this month
$jstart=tojulian($year,$month,1);
$jend=tojulian($year,$month+1,0);
$jtoday=juliantoday();
monthflipper($year,$month);
# name of this month
print "$monthnames[$month-1] $year
\n";
# main calendar table
print "\n";
# top row for days of the week
print "";
for $i (0..6) {
print "| $daynames[$i] | ";
}
print "
\n";
# figure out which day to start with...
$j = $jstart - ($jstart+1)%7;
$day = (fromjulian($j))[2];
# display the body of the calendar
while($j <= $jend) {
# next row
print "";
# for each day of the week...
for $cols (0..6) {
# figure out how to display it
$preday="";
$postday="";
$clr=$CALBG;
if ($j < $jstart || $j > $jend) {
# day not in this month
$clr=$NOTINMONTH;
$preday="";
$postday="";
}
if ($j == $jtoday) {
# today
$clr=$TODAY;
$preday="";
$postday="";
}
if ($links) {
# enable link on each day
$preday="$preday";
$postday="$postday";
}
if (length $events{$j}) {
# there's an event today
$preday=$preday."** ";
$clr=$EVENT unless $clr eq $NOTINMONTH;
}
if ($j == $jul) {
# selected color
$clr=$SELECTED;
}
# display the day
print "| $preday$day$postday | ";
# next day...
$day++; $j++;
# check if it's first or last day of month
if($j == $jstart || $j == $jend+1) {
$day=1;
}
}
print "
\n";
}
print "
\n";
return;
}
# calculate the julian day
# ------------------------
# input: year, month, day
# output: julian_date
#
# to be safe, you should call this function with 4 digit years
#
sub tojulian {
use integer;
my($year, $month, $day) = @_;
# handle 2-digit years this way:
# 00..69 => 2000..2069
# 70..99 => 1970..1969
if ($year < 70) {
$year+=2000;
} elsif ($year < 100) {
$year+=1900;
}
return $day - 32075
+ 1461 * ( $year + 4800 - ( 14 - $month ) / 12 ) / 4
+ 367 * ( $month - 2 + ( ( 14 - $month ) / 12 ) * 12 ) / 12
- 3 * ( ( $year + 4900 - ( 14 - $month ) / 12 ) / 100 ) / 4;
}
# converts julian day to year, month and day
# ------------------------------------------
# input: julian_date
# output: year, month, day
#
sub fromjulian {
use integer;
my($jd) = @_;
my($jdate_tmp,$m,$d,$y);
$jdate_tmp = $jd - 1721119;
$y = (4 * $jdate_tmp - 1) / 146097;
$jdate_tmp = 4 * $jdate_tmp - 1 - 146097 * $y;
$d = $jdate_tmp/4;
$jdate_tmp = (4 * $d + 3)/1461;
$d = 4 * $d + 3 - 1461 * $jdate_tmp;
$d = ($d + 4)/4;
$m = (5 * $d - 3) / 153;
$d = 5 * $d - 3 - 153 * $m;
$d = ($d + 5) / 5;
$y = 100 * $y + $jdate_tmp;
if ($m < 10) {
$m += 3;
} else {
$m -= 9;
++$y;
}
return ($y, $m, $d);
}
# returns today's julian date
# ---------------------------
# output: julian_date
#
sub juliantoday {
# current date
my($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) =
localtime(time);
$year+=($year < 70) ? 2000 : 1900;
return tojulian($year, $month + 1, $day);
}
# provides 3 links: last month, this month and next month
sub monthflipper {
my($year,$month)=@_;
# links to other months
print "\n";
}
# displays a list of events for the given julian date
sub showdaysevents {
my($date)=shift;
my($d,$event,$year,$month,$day);
# convert the julian date into something that's readable
($year,$month,$day)=fromjulian($date);
print "
Events for ",$monthnames[$month-1]," ",
$day,", ",$year,"";
print " (",fromtoday($date),")
\n";
if (length $events{$date}) {
print $events{$date};
} else {
print "Nothing scheduled
\n";
}
}
# returns the number of days from today
# to the given julian date
sub fromtoday {
my($date)=shift;
my($days,$d);
$d=$date-juliantoday();
if ($d==1) {
return "Tomorrow";
} elsif ($d==0) {
return "Today";
} elsif ($d==-1) {
return "Yesterday";
} elsif ($d > 1) {
return "$d days from today";
} else {
$d=-$d;
return "$d days ago";
}
}
# reads the calendar.txt file from disk
sub loadcalfile {
open F, $calfile or print "Can't open $calfile\n";
while () {
chomp;
($d,$event)=split(/,/,$_,2);
if ($d =~ m#([0-9]+)/([0-9]+)/([0-9]+)#) {
if ($datefmt==1) {
# convert m/d/y into julian date
$m=$1; $d=$2; $y=$3;
} elsif ($datefmt==2) {
# convert d/m/y into julian date
$m=$2; $d=$1; $y=$3;
} elsif ($datefmt==3) {
# convert y/m/d into julian date
$m=$2; $d=$3; $y=$1;
} else {
# oops:
die "datefmt is set incorrectly\nPlease correct it\n";
}
$d=tojulian($y,$m,$d);
}
# save the event
$events{$d}="$events{$d}$event
";
}
close F;
}