#!/v/guest/sw/bin/perl -w ############################################################################### ## ## ## Copyright (c) 2001 - 2009 by Steffen Beyer. ## ## All rights reserved. ## ## ## ## This program is free software; you can redistribute it ## ## and/or modify it under the same terms as Perl itself. ## ## ## ############################################################################### ####################################### ## ## ## See /calendar/ for a "live" ## ## example of this CGI script. ## ## ## ####################################### BEGIN { eval { require bytes; }; } use strict; use Date::Calc qw(:all); use Date::Calendar::Profiles qw($Profiles); use Date::Calendar; my $filler = '

 

'; my $RED = ''; my $PINK = ''; my $END = ''; my $language = 6; my $country = 'NL'; my $select = 0; my $dispyear = 0; my $weekend = ''; my @DOW = (); my @html = (); my @start = (); my @markwend = (); my @marksele = (); my @markyear = (); my @language = (); my @sortlang = (); my @marklang = (); my %profiles = (); my %sortprof = (); my %markprof = (); my %weekend = (); my %sdm = (); &init_tables(); &process_profiles(); &process_query_string(); &set_defaults(); &print_page(); exit 0; sub init_tables() { my $i; local $_; $html[0x00] = ''; $html[0x01] = ''; $html[0x02] = ''; $html[0x03] = ''; $html[0x04] = ''; $html[0x05] = ''; $html[0x06] = ''; $html[0x07] = ''; $html[0x08] = ''; # $html[0x09] = ''; # $html[0x0A] = ''; $html[0x0B] = ''; $html[0x0C] = ''; $html[0x0D] = ''; $html[0x0E] = ''; $html[0x0F] = ''; $html[0x10] = ''; $html[0x11] = ''; $html[0x12] = ''; $html[0x13] = ''; $html[0x14] = ''; $html[0x15] = ''; $html[0x16] = ''; $html[0x17] = ''; $html[0x18] = ''; $html[0x19] = ''; $html[0x1A] = ''; $html[0x1B] = ''; $html[0x1C] = ''; $html[0x1D] = ''; $html[0x1E] = ''; $html[0x1F] = ''; $html[0x22] = '"'; $html[0x26] = '&'; # $html[0x27] = '''; $html[0x3C] = '<'; $html[0x3E] = '>'; $html[0x7F] = ''; $html[0x80] = ''; $html[0x81] = ''; $html[0x82] = ''; $html[0x83] = ''; $html[0x84] = ''; $html[0x85] = ''; $html[0x86] = ''; $html[0x87] = ''; $html[0x88] = ''; $html[0x89] = ''; $html[0x8A] = ''; $html[0x8B] = ''; $html[0x8C] = ''; $html[0x8D] = ''; $html[0x8E] = ''; $html[0x8F] = ''; $html[0x90] = ''; $html[0x91] = ''; $html[0x92] = ''; $html[0x93] = ''; $html[0x94] = ''; $html[0x95] = ''; $html[0x96] = ''; $html[0x97] = ''; $html[0x98] = ''; $html[0x99] = ''; $html[0x9A] = ''; $html[0x9B] = ''; $html[0x9C] = ''; $html[0x9D] = ''; $html[0x9E] = ''; $html[0x9F] = ''; $html[0xA0] = ' '; $html[0xA1] = '¡'; $html[0xA2] = '¢'; $html[0xA3] = '£'; $html[0xA4] = '¤'; $html[0xA5] = '¥'; $html[0xA6] = '¦'; $html[0xA7] = '§'; $html[0xA8] = '¨'; $html[0xA9] = '©'; $html[0xAA] = 'ª'; $html[0xAB] = '«'; $html[0xAC] = '¬'; $html[0xAD] = '­'; $html[0xAE] = '®'; $html[0xAF] = '¯'; $html[0xB0] = '°'; $html[0xB1] = '±'; $html[0xB2] = '²'; $html[0xB3] = '³'; $html[0xB4] = '´'; $html[0xB5] = 'µ'; $html[0xB6] = '¶'; $html[0xB7] = '·'; $html[0xB8] = '¸'; $html[0xB9] = '¹'; $html[0xBA] = 'º'; $html[0xBB] = '»'; $html[0xBC] = '¼'; $html[0xBD] = '½'; $html[0xBE] = '¾'; $html[0xBF] = '¿'; $html[0xC0] = 'À'; $html[0xC1] = 'Á'; $html[0xC2] = 'Â'; $html[0xC3] = 'Ã'; $html[0xC4] = 'Ä'; $html[0xC5] = 'Å'; $html[0xC6] = 'Æ'; $html[0xC7] = 'Ç'; $html[0xC8] = 'È'; $html[0xC9] = 'É'; $html[0xCA] = 'Ê'; $html[0xCB] = 'Ë'; $html[0xCC] = 'Ì'; $html[0xCD] = 'Í'; $html[0xCE] = 'Î'; $html[0xCF] = 'Ï'; $html[0xD0] = 'Ð'; $html[0xD1] = 'Ñ'; $html[0xD2] = 'Ò'; $html[0xD3] = 'Ó'; $html[0xD4] = 'Ô'; $html[0xD5] = 'Õ'; $html[0xD6] = 'Ö'; $html[0xD7] = '×'; $html[0xD8] = 'Ø'; $html[0xD9] = 'Ù'; $html[0xDA] = 'Ú'; $html[0xDB] = 'Û'; $html[0xDC] = 'Ü'; $html[0xDD] = 'Ý'; $html[0xDE] = 'Þ'; $html[0xDF] = 'ß'; $html[0xE0] = 'à'; $html[0xE1] = 'á'; $html[0xE2] = 'â'; $html[0xE3] = 'ã'; $html[0xE4] = 'ä'; $html[0xE5] = 'å'; $html[0xE6] = 'æ'; $html[0xE7] = 'ç'; $html[0xE8] = 'è'; $html[0xE9] = 'é'; $html[0xEA] = 'ê'; $html[0xEB] = 'ë'; $html[0xEC] = 'ì'; $html[0xED] = 'í'; $html[0xEE] = 'î'; $html[0xEF] = 'ï'; $html[0xF0] = 'ð'; $html[0xF1] = 'ñ'; $html[0xF2] = 'ò'; $html[0xF3] = 'ó'; $html[0xF4] = 'ô'; $html[0xF5] = 'õ'; $html[0xF6] = 'ö'; $html[0xF7] = '÷'; $html[0xF8] = 'ø'; $html[0xF9] = 'ù'; $html[0xFA] = 'ú'; $html[0xFB] = 'û'; $html[0xFC] = 'ü'; $html[0xFD] = 'ý'; $html[0xFE] = 'þ'; $html[0xFF] = 'ÿ'; $start[0] = [Today()]; $start[1] = [Week_of_Year(@{$start[0]})]; for ( $i = 1; $i <= Languages(); $i++ ) { $_ = Language_to_Text($i); $language[$i] = html($_); $sortlang[$i] = iso_coll(iso_lc($_)); } %sdm = ( 'BLN' => 'Berlin', 'BON' => 'Bonn', 'CGN' => 'Köln', 'DET' => 'Detroit (USA)', 'FFM' => 'Frankfurt a.M.', 'HAN' => 'Hannover', 'HH' => 'Hamburg', 'MUC' => 'München', 'RAT' => 'Ratingen (Düsseldorf)', 'STG' => 'Stuttgart', 'ZRH' => 'Zürich (Schweiz)' ); %profiles = map { $_, $_ } keys(%{$Profiles}); } sub process_profiles() { my $profile = $INC{'Date/Calendar/Profiles.pm'}; my($read,$cache,$line,$key); $read = 1; if (defined($profile) and $profile ne '' and -f $profile and -r $profile and -s $profile) { $cache = $0; $cache =~ s!\.+[^/\\\.]*$!!; $cache .= ".cache"; if (!(-f $cache and -s $cache) or ((stat($cache))[9] < (stat($profile))[9])) { if (open(PROFILE, "<$profile")) { if (open(CACHE, ">$cache")) { while (defined ($line = )) { if ($line =~ m!^\s*\$Profiles->{'([A-Za-z]+(?:-[A-Za-z]+)?)'}\s*=\s*\#\s*(.+?)\s*$!) { $profiles{$1} = $2; } } foreach $key (keys %profiles) { if ($key =~ m!^([A-Za-z]+)-([A-Za-z]+)$! and defined $profiles{$1}) { if ($1 eq 'sdm') { $profiles{$key} = $profiles{$1} . " - " . $sdm{$2}; } else { $profiles{$key} = $profiles{$1} . " - " . $profiles{$key}; } } } foreach $key (sort keys(%profiles)) { printf(CACHE "%8s => %s\n", $key, $profiles{$key}); $read = 0; } close(CACHE); } close(PROFILE); } } } if ($read and -f $cache and -r $cache and -s $cache) { if (open(CACHE, "<$cache")) { while (defined ($line = )) { if ($line =~ m!^\s*([A-Za-z]+(?:-[A-Za-z]+)?)\s*=>\s*(.+?)\s*$!) { $profiles{$1} = $2; } } close(CACHE); } } foreach $key (keys(%profiles)) { $line = $profiles{$key}; $profiles{$key} = html($line); $sortprof{$key} = iso_coll(iso_lc($line)); } } sub process_query_string() { my $query = $ENV{'QUERY_STRING'} || $ENV{'REDIRECT_QUERY_STRING'} || 'weekend=6-7'; my @pairs = split(/&/, $query); my($pair,$var,$val,$dow); %weekend = (); foreach $pair (@pairs) { ($var,$val) = split(/=/,$pair,2); if ($var =~ m!^[a-z]+$!) { if ($var eq 'select') { if ($val =~ m!^[0-9]+$!) { $select = $val ? 1 : 0; } } elsif ($var eq 'weekend') { if ($val =~ m!^[1-7]$!) { $weekend{$val} = 1; } elsif ($val =~ m!^[1-7](?:-[1-7])+$!) { foreach $dow (split(/-/,$val)) { $weekend{$dow} = 1; } } } elsif ($var eq 'dispyear') { if ($val =~ m!^[0-9]+$! and $val >= 0 and $val <= 2) { $dispyear = $val; } } elsif ($var eq 'language') { if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= Languages()) { $language = $val; } } elsif ($var eq 'country') { if ($val =~ m!^[A-Za-z]+(?:-[A-Za-z]+)?$! and defined $profiles{$val}) { $country = $val; } } elsif ($var eq 'myear') { if ($val =~ m!^[0-9]+$! and $val >= 1583 and $val <= 2299) { $start[0][0] = $val; } } elsif ($var eq 'month') { if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= 12) { $start[0][1] = $val; } } elsif ($var eq 'week') { if ($val =~ m!^[0-9]+$! and $val >= 1 and $val <= 53) { $start[1][0] = $val; } } elsif ($var eq 'wyear') { if ($val =~ m!^[0-9]+$! and $val >= 1583 and $val <= 2299) { $start[1][1] = $val; } } } } $weekend{0} = 1 unless (scalar(keys(%weekend))); $weekend = join('-',sort(keys(%weekend))); } sub set_defaults() { my $year; local $_; @markwend = ('') x 8; @marksele = ('', ''); @markyear = ('', '', ''); @marklang = ('') x (Languages() + 1); %markprof = map { $_, '' } keys(%profiles); $markwend[$_] = ' CHECKED' foreach (keys %weekend); $marksele[$select] = ' CHECKED'; $markyear[$dispyear] = ' CHECKED'; $marklang[$language] = ' SELECTED'; $markprof{$country} = ' SELECTED'; if ($dispyear > 0) { if ($select) { $year = $start[1][1]; } else { $year = $start[0][0]; } $start[0] = [$year,1,1]; $start[1] = [1,$year]; $start[2] = Days_in_Year($year,12); $start[3] = [$year-1,1,1]; $start[4] = [1,$year-1]; $start[5] = [$year+1,1,1]; $start[6] = [1,$year+1]; } else { if ($select) { $_ = Weeks_in_Year($start[1][1]); $start[1][0] = $_ if ($start[1][0] > $_); $start[0] = [Monday_of_Week(@{$start[1]})]; $start[2] = 28; $start[3] = [Add_Delta_Days(@{$start[0]},-28)]; $start[4] = [Week_of_Year(@{$start[3]})]; $start[5] = [Add_Delta_Days(@{$start[0]},+28)]; $start[6] = [Week_of_Year(@{$start[5]})]; } else { $start[0][2] = 1; $start[1] = [Week_of_Year(@{$start[0]})]; $start[2] = Days_in_Month(@{$start[0]}[0,1]); $start[3] = [Add_Delta_YM(@{$start[0]},0,-1)]; $start[4] = [Week_of_Year(@{$start[3]})]; $start[5] = [Add_Delta_YM(@{$start[0]},0,+1)]; $start[6] = [Week_of_Year(@{$start[5]})]; } } $DOW[$_] = html(Day_of_Week_Abbreviation($_,$language)) foreach (1..7); } sub print_page() { my($i,$key); print <<"VERBATIM"; Content-type: text/html; charset="iso-8859-1" Steffen Beyer's International Eternal Gregorian Calendar


Steffen Beyer's International Eternal Gregorian Calendar


Your language:
Your country:
Select by:  Year and Month  Week and Year
$filler Year (1583..2299): Week (1..53):
$filler Month (1..12): Year (1583..2299):
Display a:
 Month  Year: days off only  Year: all named days
Weekend days:
$DOW[1] $DOW[2] $DOW[3] $DOW[4] $DOW[5] $DOW[6] $DOW[7]
${RED}Note: Historical irregularities are (usually) not taken into account!${END}


VERBATIM &print_calendar(); print <<"VERBATIM";


$filler


${RED}Please report any errors you find on this page!${END}


Download the Perl software that does all this!


VERBATIM } sub print_calendar() { my $year = 0; my $index = 0; my $oyear = 0; my $oweek = 0; my $omonth = 0; my($calendar,$full,$half,$C,$N,$cell,$week,$dow); my(@date,$tags); local $_; $calendar = Date::Calendar->new( $Profiles->{$country}, Decode_Language("English"), keys(%weekend) ); print <<"VERBATIM"; $profiles{$country} Year Week
Number
Day of
Week
Month Day Name VERBATIM @date = @{$start[0]}; while ($start[2] > 0 and $date[0] <= 2299) { if ($date[0] >= 1583) { if ($year != $date[0]) { $year = $date[0]; $index = $calendar->date2index(@date); $full = $calendar->year($year)->vec_full(); $half = $calendar->year($year)->vec_half(); } if ( ($dispyear == 0) or (($dispyear == 2) and (keys(%{$tags = $calendar->year($year)->tags($index)}))) or (($dispyear == 1) and ($full->bit_test($index) or $half->bit_test($index)) and not exists($weekend{Day_of_Week(@date)}))) { print "\n"; if ($full->bit_test($index)) { $C = $RED; $N = $END; } elsif ($half->bit_test($index)) { $C = $PINK; $N = $END; } else { $C = ''; $N = ''; } if ($oyear != $date[0]) { $oyear = $date[0]; $cell = "$oyear"; } else { $cell = $filler; } print qq($cell\n); # Year $week = Week_of_Year(@date); if ($oweek != $week) { $oweek = $week; $cell = "$week"; } else { $cell = $filler; } print qq($cell\n); # Week Number $tags = $calendar->year($year)->tags($index) unless ($dispyear == 2); $dow = html(Day_of_Week_to_Text(Day_of_Week(@date),$language)); print qq($C$dow$N\n); # Day of Week if ($omonth != $date[1]) { $omonth = $date[1]; $cell = "" . html(Month_to_Text($omonth,$language)) . ""; } else { $cell = $filler; } print qq($cell\n); # Month print qq($C$date[2]$N\n); # Day if (keys(%$tags)) { print qq(\n), # Name join ( "
\n", map { if ($tags->{$_} & 2) { $RED . html($_) . $END; } elsif ($tags->{$_} & 1) { $PINK . html($_) . $END; } else { html($_) } } keys(%$tags) ), qq(\n\n); } else { print qq($filler\n); # Name } print "\n"; } } if (--$start[2] > 0) { @date = Add_Delta_Days(@date,1); $index++; } } } sub html($) { my $string = $_[0]; my $o; $string =~ s!(.)!(defined $html[$o=ord($1)])?($html[$o]||"&\#$o;"):$1!eg; $string; } sub iso_lc($) { my $string = $_[0]; $string =~ tr/\x41-\x5A\xC0-\xD6\xD8-\xDE\x8A\x8C\x9F/\x61-\x7A\xE0-\xF6\xF8-\xFE\x9A\x9C\xFF/; $string; } sub iso_coll($) { my $string = $_[0]; $string =~ s/\xC4/Ae/g; # German $string =~ s/\xE4/ae/g; $string =~ s/\xD6/Oe/g; $string =~ s/\xF6/oe/g; $string =~ s/\xDC/Ue/g; $string =~ s/\xFC/ue/g; $string =~ s/\xDF/ss/g; $string =~ s/\xC6/AE/g; # Scandinavian $string =~ s/\xE6/ae/g; # $string =~ s/\xD8/OE/g; # $string =~ s/\xF8/oe/g; $string =~ s/\xFF/ij/g; # Dutch $string =~ s/\x9F/IJ/g; # Dutch (Non-Standard!) $string =~ s/\x8C/OE/g; # French (Non-Standard!) $string =~ s/\x9C/oe/g; # French (Non-Standard!) $string =~ tr/\x20\x2D\x5F\x30-\x39A\xC0-\xC6a\xE0-\xE6BbC\xC7c\xE7DdE\xC8-\xCBe\xE8-\xEBFfGgHhI\xCC-\xCFi\xEC-\xEFJjKkLlMmNn\xD1\xF1O\xD2-\xD6\xD8\x8Co\xF2-\xF6\xF8\x9CPpQqRrS\x8As\x9A\xDFTtU\xD9-\xDCu\xF9-\xFCVvWwXxY\xDD\x9Fy\xFD\xFFZz\xD0\xF0\xDE\xFE\x21-\x2C\x2E\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x89\x8B\x8D-\x99\x9B\x9D\x9E\xA0-\xBF\xD7\xF7/\x20-\xFF/; $string; } __END__