Feiertagsberechnung zum Import in Kalender

Beschreibung | ics-Datei erzeugen

Worum geht es?

Da wir Kalenderdienste wie sie von Konzernen im Internet angeboten werden nicht nutzen möchten, weil die Daten dort nicht mehr in unserer alleinigen Obhut sind, kam uns der Artikel Wolkenbausatz: Kalenderserver mit DAViCal und Linux in der c't 15/2011 gerade recht: Er beschreibt, wie ein Kalender auf Basis von DAViCal aufgesetzt wird und auf was dabei zu achten ist. Auch wenn dieser Artikel gebührenpflichtig ist kann ich ihn nur empfehlen.

Ist so ein Kalender erstmal aufgesetzt und mit allen Desktop-, Laptop-, Tablet- und Smartphone-Clients abruf- und bedienbar, kommt schnell der Wunsch auf, dort auch alle Feiertage eingetragen zu haben. Natürlich kann man dies jedes Jahr von Neuem per Hand tun. Man kann es aber aber auch automatisieren. Und genau hier kommt das Skript

feiertage.pl
ins Spiel: Es errechnet für ein beliebiges Jahr die Feiertage und erstellt eine ics-Datei, die in Kalender wie z.B. DAViCal und auch andere importiert werden kann.



Voraussetzungen

Osterabhängige und -unabhängige Feiertage

Prinzipiell gibt es 2 Arten von Feiertagen: Einmal die beweglichen Feiertage, die von Ostern, genauer dem Ostersonntag, abhängig sind: Und dann die Feiertage, die feststehen, also allein über ihr Datum definiert sind wie z.B.:

Die Osterformel im Skript

Für die osterabhängigen Tage muß erstmal der Ostersonntag ermittelt werden. Dies haben verschiedene historische Personen in Gleichungen gepackt. Das Skript stützt sich hier auf die Gaußsche Osterformel:

# Ostern ermitteln
my $A=$YEAR % 19;
my $B=int($YEAR / 100);
my $C=int((8*$B+13)/25)-2;
my $D = $B - int($YEAR/400) - 2;
my $E = (19 * ($YEAR % 19) + ((15 - $C + $D) % 30)) % 30;
if ($E == 28){
    if ($A > 10){
        $E = 27;
    }
} elsif ($E == 29){
    $E = 28;
}
my $F = ($D + 6 * $E + 2 * ($YEAR % 4) + 4 * ($YEAR % 7) + 6) % 7;
my $ostersonntag=timelocal(0,0,0,1,2,$YEAR)+($E+$F+21)*86400;

Ist der Ostersonntag erst einmal ermittelt, ist das Datum der osterabhängigen Tage auch klar.

Weitere Feiertage & Termine eintragen

Nicht in allen Bundesländern sind die Feiertage gleich. Während Berlin, Bremen, Hamburg, Niedersachsen und Schleswig-Holstein nur 9 gesetzliche Feiertage im Jahr haben sind es in Bayern 13. Daher ist es möglich, selbst Feiertage einzutragen.

Der Syntax ist recht einfach:

$feiertag{timelocal(0,0,0,Tag,Monat,$YEAR)}="Name des Feiertages";

WICHTIG: Der Monat fängt bei 0 an zu zählen: Für den Januar also eine 0 eintragen, für Februar eine 1 usw. Für die Heiligen 3 Könige am 6. Januar (in Bayern ein Feiertag) ist der Eintrag wie folgt:

$feiertag{timelocal(0,0,0,6,0,$YEAR)}="Hl. 3 Könige";

In dem Abschnitt "eigene Tage" sind schon drei voreingestellt:

# eigene Tage
$feiertag{timelocal(0,0,0,6,0,$YEAR)}="Hl. 3 Könige";
$feiertag{timelocal(0,0,0,14,1,$YEAR)}="Valentinstag";
$feiertag{timelocal(0,0,0,31,9,$YEAR)}="Halloween";

Möchte man einen Tag deaktivieren, also dass er nicht in die ics-Datei geschrieben wird, muss man die entsprechende Zeile löschen oder eine Raute "#" voranstellen.

Auch ließe sich so ein Hochzeitstag oder Geburtstag eintragen. Praktisch, wenn man dazu neigt, diese doch mal zu vergessen ... ;-)

Skript aufrufen und eine ics-Datei erzeugen

Beim Aufruf des Skriptes muß das Jahr, für das die ics-Datei mit den Feiertagen erzeugt werden soll, 4-stellig angegeben werden, ansonsten bricht das Skript mit einer Fehlermeldung ab. Um für das Jahr 2014 die Feiertage zu berechnen wäre der Aufruf wie folgt:

perl feiertage.pl 2014

Das Skript berechnet die Feiertage für 2014 und schreibt sie in die Datei

feiertage_2014.ics
Eigentlich ist man hier schon am Ziel: Man hat die Datei "feiertage_2014.ics", in der alle Feiertage enthalten sind. Diese Datei kann nun in Kalender importiert werden, die auf das iCalendar-Format aufsetzen.

Entweder macht man dies manuell in dem Kalenderprogramm, indem man die ics-Datei öffnet und so einlädt, oder ...

ics-Datei automatisch in DAViCal eintragen

... man läßt dies elegant jedes Jahr automatisch ablaufen. Bei uns läuft jedes Jahr in der Neujahrsnacht um 2:25 Uhr das Skript feiertage_eintragen.sh als cronjob

25 2 1 1 *  root  <Pfad-in-dem-das-Skript-liegt>/feiertage_eintragen.sh
Es ermittelt das aktuelle Jahr und inkrementiert es um eins und ruft feiertage.pl auf. In der Neujahrsnacht 2015 werden also die Feiertage für 2016 eingetragen. So hat man immer die Feiertage der 2 nächsten Jahre in DAViCal eingetragen und kann entsprechend planen. Wem dies zuweit in die Zukunft ist kann dies im Skript ändern:
###
# Jahr ermitteln (läuft Anfang Januar, also aktuelles Jahr+1)
echo -n "`date +%T`: ermittle Jahr, das eingetragen werden soll: " >> ${LOG}
DAVICALYEAR=$((`date +%Y`+1))
echo "${DAVICALYEAR}" >> ${LOG}
In der Zeile, in der DAVICALYEAR zugewiesen wird, kann der Parameter ‘+1’ weggenommen werden. Dann werden die Feiertage für das aktuelle Jahr ermittelt und in DAViCal eingetragen.

Auf jeden Fall müssen aber vorher der ADMIN und und das Passwort der PostgreSQL-Datenbank angegeben werden, damit das Skript die erzeugte ics-Datei auch in die Datenbank einschreiben kann:

###
# Einstellungen
ADMIN="admin"
PW="geheim"
SERVER=`hostname -f`

DAViCal-Backup

Natürlich sollte auch ein Backup gemacht werden. Das macht das Skript

backup_davical.sh
Es schreibt den Inhalt der PostgreSQL-Datenbank in eine ics-Datei. Diese kann bei einem Platten-/Computer-Crash nach Neuaufsetzen von DAViCal wieder zurückgeschrieben werden - es gehen keine Termine verloren.

Bei uns läuft dies Backup-Skript jede Nacht, somit ist der maximale Verlust der eingegebenen Daten auf die letzten 24 Stunden beschränkt.

Aber auch hier müssen die Zugangsdaten zu der Datenbank eingegeben werden:

###
# Einstellungen
ADMIN="admin"
PW="geheim"
SERVER=`hostname -f`

Download "feiertage.tar.gz"

Das Paket enthält:

Und hier das Paket:

ics-Datei erzeugen

Hier kann man sich eine ics-Datei für ein bestimmtes Jahr erstellen lassen und downloaden: ics-Datei erzeugen

Autor

Dirk Schimansky

Bei Fragen einfach eine E-Mail schreiben.

Spende

Wer Lust hat: Bitte schön, auch ich trinke gerne mal ein Bier! :-)

Danke!

Quellen



17.01.2012 - Tools - Dirk Schimansky - Impressum