Douba/Kalender

Stand vom 07.07.2013


Douba.de

Universität

Reisen

Projekte

Hobbies

Freunde

Links

Valid HTML 4.01 Strict CSS ist valide!

Doubas Kalender

Heute ist Dienstag, der 20. Februar 2018. Es ist 22:39 Uhr und 46 Sekunden.

Jede Woche beginnt mit einem Montag.

Dieser Monat begann mit einem Donnerstag und endet mit einem Mittwoch.

Daraus ergeben sich ein Vorlauf von 3 Tagen und ein Nachlauf von 4 Tagen.

Dargestellt wird demnach die Zeit zwischen Montag, dem 29. Januar 2018 und Sonntag, dem 4. März 2018.

Der Kalendermonat benötigt zur Darstellung also Platz für 35 Tage bzw. 5 Wochen.

Februar 2018
MontagDienstagMittwochDonnerstagFreitagSamstagSonntag
2930311234
567891011
12131415161718
19202122232425
2627281234

Bemerkungen

Am 25.1.2010 ist meine Seite auf den normalen AFS-Server umgezogen, der inzwischen auch MySQL zur Verfügung stellt. Seitdem funktioniert auch die Anzeige des Kalenders wieder.

Im Zuge der Überarbeitung meiner Homepage habe ich herausgefunden, daß es zulässig ist, einem HTML-Element mehrere Klassen zuzuordnen. Dies geschieht, indem man sie durch Leerzeichen getrennt in das Attribut schreibt, zum Beispiel so: <td class="holiday overhang"> — diese Information ließe sich prima im Kalenderskript verwenden. Das mache ich aber erst, wenn ich wieder Zeit habe.

Hier der Quelltext (der Übersichtlichkeit halber am besten kopieren und mit einem Syntax-Highlighter betrachten):

#!c:/Development/xampp/Perl/bin/perl.exe

#################################
## Doubas Kalender             ##
## Version 1.0                 ##
## geschrieben von Ingo Schupp ##
## 14.8.2007                   ##
#################################

##########
## Init ##
##########

use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard *table *Tr/;
use strict;
use Time::Local;

print "Context-type:text/html\n\n";

##################
## Definitionen ##
##################

my @monat=qw(Januar Februar März April Mai Juni Juli August September Oktober November Dezember);
my @tag=qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag);

my $oneSec=1;
my $oneMin=60*$oneSec;
my $oneHour=60*$oneMin;
my $oneDay=24*$oneHour;
my $oneWeek=7*$oneDay;

###########
## Input ##
###########

## Zeitpunkt ##
my $time=time;  # Ortszeit zum Zeitpunkt des Aufrufs

## Parameter ##
my $weekStartsWithDOW=1;  # Wochen beginnen montags!

################
## Berechnung ##
################

#    0    1    2     3     4    5     6     7     8
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($time);  # gespeicherten Zeitpunkt (im Folgenden: ZP) in Bestandteile zerlegen
my $jahr=$year+1900;  # Jahresangabe ist sonst relativ zum Jahr 1900.

print h1("Doubas Kalender")."\n";
print p("Heute ist $tag[$wday], der $mday. $monat[$mon] $jahr. Es ist $hour:$min Uhr und $sec Sekunden.")."\n";

my $monthStartsWithTime=timelocal($sec,$min,$hour,1,$mon,$year);  # den 1. Tag im Monat des ZP ermitteln
my $monthStartsWithDOW=(localtime($monthStartsWithTime))[6];  # sowie den zugehörigen Wochentag.
my $monthEndsWithTime=timelocal($sec,$min,$hour,1,($mon+1)%12,$year+(($mon==12)?1:0))-$oneDay;  # den ersten Tag des Folgemonats ermitteln, bei Überlauf die
  # Jahreszahl erhöhen, das ganze in Sekunden umrechnen und dann einen ganzen Tag abziehen. So erhält man den letzten Tag des Monats.
my $monthEndsWithDOW=(localtime($monthEndsWithTime))[6];  # wieder den zugehörigen Wochentag ermitteln.
print p("Jede Woche beginnt mit einem $tag[$weekStartsWithDOW].")."\n";
print p("Dieser Monat begann mit einem $tag[$monthStartsWithDOW] und endet mit einem $tag[$monthEndsWithDOW].")."\n";

my $numOfPreDays=(7+$monthStartsWithDOW-$weekStartsWithDOW)%7;  # Auf Basis des gewünschten Starttages jeder Woche werden die Anzahl der zusätzlich darzu-
my $numOfPostDays=(6+$weekStartsWithDOW-$monthEndsWithDOW)%7;  # stellenden Tage vor und nach dem Monat ermittelt, so daß ganze Wochen angezeigt werden.
my $viewStartsWithTime=$monthStartsWithTime-$oneDay*$numOfPreDays;  # Der genaue Startzeitpunkt der Anzeige (View) wird errechnet
my $viewEndsWithTime=$monthEndsWithTime+$oneDay*$numOfPostDays;  # wie auch der Endzeitpunkt.
my @temp=localtime($viewStartsWithTime);  # In einer Hilfsvariable wird der zerlegte View-Start-ZP gespeichert.
my $tempyear=$temp[5]+1900;  # Das absolute Jahr wird errechnet
my $viewStartsWithString="$tag[$temp[6]], dem $temp[3]. $monat[$temp[4]] $tempyear";  # und das ganze menschenlesbar gemacht.
@temp=localtime($viewEndsWithTime);  # Dasselbe geschieht mit dem View-End-ZP.
my $tempyear=$temp[5]+1900;
my $viewEndsWithString="$tag[$temp[6]], dem $temp[3]. $monat[$temp[4]] $tempyear";
my $viewCoversDays=(($monthEndsWithTime-$monthStartsWithTime)/$oneDay)+$numOfPreDays+$numOfPostDays+1;  # Die "Dauer" des Views in ganzen Tagen wird errechnet.
my $viewCoversWeeks=$viewCoversDays/7;  # Dies durch sieben geteilt (sollte immer teilbar sein!) ergibt die Anzahl der darzustellenden Wochen.
print p("Daraus ergeben sich ein Vorlauf von $numOfPreDays Tagen und ein Nachlauf von $numOfPostDays Tagen.")."\n";
print p("Dargestellt wird demnach die Zeit zwischen $viewStartsWithString und $viewEndsWithString.")."\n";
print p("Der Kalendermonat benötigt zur Darstellung also Platz für $viewCoversDays Tage bzw. $viewCoversWeeks Wochen.")."\n";

#############
## Ausgabe ##
#############

my $i;  # Zähler.
print start_table({-class=>"calendar",-cellspacing=>0})."\n";
print Tr(th({-colspan=>"7",-class=>"month"},"$monat[$mon] $jahr"))."\n";  # Der Monat wird als überschrift dargestellt.
print start_Tr();  # Darauf folgen die Wochentage
for ($i=0;$i<7;$i+=1) {
	print th($tag[($i+$weekStartsWithDOW)%7]);  # beginnend mit dem gewünschten Wochentag. % ist der Modulo-Operator.
}
print end_Tr()."\n";

for ($i=$viewStartsWithTime;$i<=$viewEndsWithTime;$i+=$oneDay) {  # Zählen vom Anfang bis zum Ende des Views. Schrittweite sind ganze Tage.
	my @itime=localtime($i);  # Aktuellen Zeitpunkt zerlegen
	my $DOW=$itime[6];  # Dazu den reellen Wochentag ermitteln
	my $viewDOW=(($i-$viewStartsWithTime)/$oneDay)%7;  # aber auch die Nummer der Tabellenspalte, in der der Tag angezeigt wird.
	  # Dies hängt vom gewünschten Beginn der Woche ab. Ist dies der Sonntag, so sind $DOW und $viewDOW identisch.
	print start_Tr if $viewDOW==0;  # Vor jeder ersten Zelle eine neue Zeile anfangen
	my $class="";  # Voreinstellung für die Zelle: keine Klasse
	$class="holiday" if $DOW==0;  # Sonntage werden als Feiertag markiert.
	$class="overhang" if (($i<$monthStartsWithTime) || ($i>$monthEndsWithTime));  # Überhangtage werden als solche markiert.
	my $id="";  # Voreinstellung: keine Bezeichnung
	$id="today" if $i==$time;  # Wenn der ZP an der Reihe ist, wird dieser als der heutige Tag markiert.
	if ($class eq "") {  # Abhängig davon, ob jeweils Klasse und ID angegeben sind, werden diese Attribute im Zellen-Tag angegeben oder weggelassen.
		if ($id eq "") {
			print td($itime[3]);
		} else {
			print td({-id=>$id},$itime[3]);
		}
	} else {
		if ($id eq "") {
			print td({-class=>$class},$itime[3]);
		} else {
			print td({-class=>$class,-id=>$id},$itime[3]);
		}
	}
	print end_Tr."\n" if $viewDOW==6;
}

print end_table();
			

Und das Stylesheet:

table.calendar {
	border:thick outset #7FFFD4;
	border-collapse:separate;
	background-color:#7FFFD4;
	padding:1ex;
}

th {
	padding-left:1ex;
	padding-right:1ex;
}

th.month {
	border:medium inset #7FFFD4;
	background-color:#008B8B;
	color:#FFF8DC;
	font-size:x-large;
	font-family:sans-serif;
}

td {
	border:medium inset #7FFFD4;
}

td#today {
	border-color:#E9967A;
}

td.overhang {
	background-color:#DCDCDC;
	color:#696969;
}

td.holiday {
	color:red;
}

pre {
	border:thin solid black;
	padding:2ex;
	margin:2ex;
	background-color:#FFF8DC;
	font-size:small;
}
			

—Ingo Schalk-Schupp — alle Rechte vorbehalten