Kalenderberechnungen

Motivation

Wäh­rend meiner Tä­tig­keit als Soft­ware­ent­wick­ler kam ich im­mer wie­der mit der Be­rech­nung von Ka­len­der­da­ten in Be­rüh­rung. Die da­bei be­nutz­ten Al­go­rith­men und deren Er­wei­te­rungen möch­te ich hier dar­stel­len.

Da­bei ent­steht eine Ab­hand­lung über Ka­len­der­al­go­rith­men, der Ver­such ih­rer Er­klä­rung und das Pro­to­koll ei­ner Um­setz­ung in die ver­schie­den­sten Pro­gram­mier­spra­chen.

Vorbemerkungen

Alle Beispiele sind in keiner bestimmten Programmier­sprache formu­liert. Mir kommt es zu­nächst nur darauf an, die Algo­rithmen zu zeigen. Die Umsetzung in konkrete Programmier­sprachen erläutere ich später. In diesem zweiten Teil der Abhandlung gehe ich von einem System aus, in dem es auf irgend­eine Weise möglich ist, einer Funktion mehrere Paramenter mit­zugeben, wie auch der auf­rufenden Funktion mehrere Werte zurück­zugeben.

Die Julianische Tageszahl

In meinem privaten Umfeld kam ich bei meiner Ahnenforschung schnell an die Grenzen der gängigen Darstellung des Kalender­datums. Die Betriebs­systeme z.B. zählen die Sekunden seit 1.1.1970. Ich bin 1963 geboren. Dieses Datum kann ich also schon nicht mehr mit gängigen Board­mitteln des Betriebs­systems darstellen; was erst recht für meine Ahnen gilt ;-) Auf der Suche nach einer Lösung kam ich schnell auf Algorithmen, die zwischen einem gegebenen Datum und der Julianischen Tages­zahl wandeln.

Die Julianische Tageszahl bezeichnet einen Zeit­strahl gemessen in Tagen beginnend mit dem 1.1.4713 vor Christus. Hier der erste Algorithmus, mit dem ich in Kontakt kam. Er wandelt das Datum bestehend aus Tag, Monat, Jahr in die Julianische Tageszahl um. Gerechnet wird mit der Schaltjahresrechnung des Gregorianischen Kalenders, der am 4. Oktober 1582 eingeführt wurde und seit dem gültig ist.

[1] if month <= 2 then
[2]    month = month + 12
[3]    year = year - 1
[4] endif
[5] b = (int)(year/400) - (int)(year/100) + (int)(year/4)
[6] a = 365.0*year + 1720997;
[7] jd0 = a + b + (int)(30.6001*(month+1)) + day

Bevor der Januar zum ersten Monat des Jahres erklärt wurde, begann das Jahr mit dem Monat März. Das kann man unter anderem daran erkennen, dass die Monate Oktober, November und Dezember die 8, 9 und 10 in ihrem Namen tragen. Damit stand der Februar als Monat mit dem Schalttag am Ende des Jahres. Das war sehr viel praktischer bei jeglichen Kalenderberechungen. In der Zeile [1] bis [4] unseres Algorithmus wird der Januar zum 13. und der Februar zum 14. Monat des vorhergehenden Jahres.

Unser Kalenderjahr richtet sich nach der Sonne aus und dauert fast genau so lange, wie eine Umrundung der Erde um die Sonne. Das sind 365,2422 Tage. Der Tag des Gregorianischen Kalenders ist 365,2425 Tage lang. Den noch verbleibenden Unterschied von 0,0003 Tagen wird mit Schaltsekunden korrigiert und ist für unsere Betrachtungen nicht relevant. In der Zeile [5] werden die Schalttage seit der Zeitenwende berechnet.

Ein Jahr ohne Schalttag hat 365 Tage. In Zeile [6] werden die Tage in Gemeinjahren, d.h. ohne Schalttage seit der Zeitenwende zu dem Julianischen Tag der Zeitenwende addiert. Wobei hier eine Differenz zum tatsächlichen Julianischen Tag der Zeitenwende existiert. [???] Dies erklärt sich damit, dass das aktuelle Jahr multipliziert wird und die Schalttage keine Beachtung finden, da sie in Zeile [5] schon berechnet werden.

In Zeile [7] wird ein Algorithmus verwendet, der mich immer wieder fasziniert. Die Monate beginnend mit dem März haben folgende Reihe ihrer Längen. März (31), April (30), Mai (31), Juni (30), Juli (31), August (31), September (30), Oktober (31), November (30), Dezember (31), Januar (31), Februar (der Rest): 31 30 31 30 31 | 31 30 31 30 31 | 31 Rest. Jetzt wird klar, dass es hier eine Zahl braucht, mit der man den Monat multiplizieren kann und die eine solche Folge produziert: 30.6001 hat ein kluger Kopf gefunden. Zu dieser Konstante wird der Monat um eins erhöht addiert; erinnern wir uns doch daran, dass in Zeile [1] bis [4] der Anfang des Jahres auf März verschoben wird. Deshalb zählen die Monate 3 = März bis 14 = Februar. In Zeile [7] werden dann noch die Ergebnisse aus Zeile [5] und Zeile [6] zuaddiert. Damit ist die Julianische Tageszahl errechnet-

Dieser Algorithmus ist nur gültig seit der Gregorianschen Kalenderreform 1582. Für die Zeit davor gilt der Julianische Kalender, für den wir später die entsprechenden Algorithmen kennen lernen dürfen.

Der folgende Algorithmus tut das Gegenteil von unserem ersten; er wandelt von der Julianischen Tageszahl zurück in Tag, Monat und Jahr. Diesen Algorithmus zu verstehen brauche ich noch einige Momente absoluter Konzentration ;-)

[1] b = (int)((jd0-1867216.25)/36524.25);
[2] c = jd0 + (b-(int)(b/4)) + 1525.0;
[3] d = (int)((c-122.1)/365.25);
[4] e = 365.0 * d + (int)(d/4);
[5] f = (int)((c-e)/30.6001);
[6] day = (int)((int)(c-e+0.5) - (int)(30.6001*f));
[7] month = (int)(f - 1 - 12*(int)(f/14));
[8] year = (int)(d - 4715 - (int)((7+month)/10));

Diese Seite ist im Auf­bau, d.h. dass Sie live an der For­mu­lier­ung Teil haben können. Wer möch­te, sen­det mir An­mer­kun­gen oder Ver­bes­ser­ungs­vor­schlä­ge per Mail: thomas.heptner[@]gmail.com

Viel Spaß dabei...


Die Um­setzung in Pro­gram­mier­spra­chen wie z.B. C, Perl, PHP kann ich gerne heraus geben, jedoch melden Sie sich dazu bitte per Mail bei mir. Ich möchte gerne den Über­blick bewahren, wozu diese Biblio­theken ein­gesetzt werden.
thomas.heptner[@]gmail.com