#! /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 ""; } 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 ""; # 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 "
$daynames[$i]
$preday$day$postday
\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 "", "", "", "", "
< Last MonthTodayNext Month >
\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; }