Die Zeitrechnung, das Datum und die Schaltjahre

Egal ob man dabei ist eine Fakturierungs-Software, ein Kontenverwaltungsprogramm oder einen Terminplaner zu schreiben, man braucht bei allen Programmierproblemen dieselbe Funktion: Eine Funktion, die die Anzahl der Tage ermittelt, die seit einem bestimmten Datum verstrichen sind. Da für manche Programmierer das Schaltjahrchaos anscheinend einen schwer überwindbaren Dschungel darstellt und schon viele falsche Veröffentlichungen zu diesem Thema gemacht wurden, habe ich mich entschlossen, diesen Artikel zu schreiben. Um nebenbei noch etwas allgemeinere Informationen über die Zeitrechnung auf unserem Planeten zu vermitteln - damit die Sektkorken zur Jahrtausendwende nicht zu früh knallen - beginnen wir einfach ganz weit in der Vergangenheit.

In Religion und Kultur fast aller Völker der Erde spielten Sonne, Mond, Planeten und Sterne eine wichtige Rolle. Deshalb richteten sich ihre Kalender entweder nach dem Mond- oder dem Sonnenlauf oder sogar nach beiden Gestirnen. Auch bei uns weist der Begriff "Monat" noch auf eine Verknüpfung mit dem Mondlauf hin. In der heutigen Zeit huldigen wir aber keinen Mondgöttern mehr und so wird der von der Bewegung des Mondes unabhängige Monat lediglich noch zur Jahresaufteilung in übersichtliche Abschnitte verwendet. Der Sinn einer modernen Zeitrechnung oder eines Kalenders ist einerseits, Zeitdifferenzen, also den Abstand bestimmter Zeitpunkte relativ zueinander genau festlegen zu können und andererseits gleiche Periodizität der an die jährliche Erdbewegung gekoppelten Zeitpunkte zu erfassen. Man denke z.B. an Aussaat und Ernte in der Landwirtschaft, an die Jahreszeit gekoppelte Feiertage und die Jahreszeiten selbst. Deshalb dürfte das Sonnenjahr, mit dem wir uns hier ausschließlich beschäftigen wollen, eine der schon am längsten bekannten Zeiteinheiten sein.

Was ist ein Jahr astronomisch gesehen?

Um das näher zu erörtern, müssen wir uns etwas mit der Astronomie beschäftigen. Die Erde umläuft die Sonne auf einer fast kreisförmigen Bahn, die sich in einer Ebene befindet, in der auch die Sonne liegt. Diese Ebene wird Ekliptik genannt. Die Jahreszeiten kommen durch unterschiedliche Sonnenscheindauer und unterschiedliche, maximale tägliche Sonnenhöhe während des Jahres an einem Ort zustande. Dabei gilt, je höher die Sonne an einem Ort steigt, desto stärker können sich Atmosphäre und Boden erwärmen. Natürlich vernachlässigen wir bei dieser Betrachtung die Thermodynamik der Erdatmosphäre und setzen voraus, was wir eigentlich nicht dürften, in der Atmosphäre erfolgt kein Wärmeaustausch. Mit dieser Annahme stellen wir fest, daß dort die Wärme am größten ist, wo die Sonne ihren höchsten Stand (den Mittag) im Zenit erreicht. Daß die maximale Sonnenhöhe an einem Ort nicht konstant ist liegt an der Schiefe der Ekliptik, d.h. daß die geographische Nord-Süd-Achse der Erde, ihre Rotationsachse also, zur Senkrechten auf der Ekliptik um 23.5 Grad geneigt ist, bzw. der Winkel zwischen Äquatorebene der Erde und der Ekliptik 23.5 Grad beträgt. Würde die Rotationsachse der Erde senkrecht auf der Ekliptik stehen, so gäbe es zwar unterschiedliche Klimazonen, aber keine Jahreszeiten.

Abb. 1: Senkrechte auf der Ekliptik und Rotationsachse der Erde schließen einen Winkel von 23.5 Grad ein.


Zwischen Frühlings- und Herbstanfang (21. März bis 23. Septmeber) wird die Nordhalbkugel und im anderen halben Jahr die Südhalbkugel bevorzugt von der Sonne beschienen. Am 21. Juni ist Sommeranfang auf der Nordhalbkugel und Winteranfang auf der Südhalbkugel: auf der Nordhalbkugel erreicht die Sonne zu diesem Zeitpunkt ihren höchsten, auf der Südhalbkugel ihren tiefsten Stand. Insofern müßte der Sommeranfang eigentlich schon "Sommermitte" und der Winteranfang "Wintermitte" heißen. Dies ist aber nicht der Fall, weil die maximal mögliche Erwärmung der maximalen Sonnenhöhe mit einer Zeitdifferenz folgt.

Abb. 2: Die Jahreszeiten auf der Nordhalbkugel



Ein Jahr ist also genau der Zeitraum, der z.B. zwischen zwei Frühlingsanfängen vergeht. Und das wäre der Zeitraum, in dem die Erde relativ zu den Sternen einmal komplett um die Sonne gelaufen ist, vorausgesetzt die Erdrotationsachse hat im Raum eine zeitlich konstante Ausrichtung (wie in Abb. 2). Leider ist das nicht genau der Fall. Die Erdachse führt infolge der Kräftewirkungen von Mond und Sonne auf die Erde eine Präzessionsbewegung aus. Diese läßt die Erdachse innerhalb von 25700 Jahren (=ein Platonisches Jahr) einmal einen Kegelmantel um eine senkrecht auf der Ekliptik stehende Achse beschreiben, ganz ähnlich der Taumelbewegung eines Kreisels. Die Präzession ist auch eine der Ursachen dafür, daß der Polarstern nicht immer der Nordstern ist.

Abb. 3: Die Präzession um die Polachse der Ekliptik (die Senkrechte auf der Ekliptik)



Dadurch ist zwar die Neigung der Erdachse gegen die Ekliptik konstant, von Frühlingsanfang bis Frühlingsanfang vergeht jedoch etwas weniger Zeit, als für genau einen Sonnenumlauf nötig wäre. Und dieser Zeitraum ist, wer hätte es gedacht, das sogenannte tropische Jahr, das wir zur Zeitrechnung verwenden. Es hat eine Länge von 365.242198 mittleren Sonnentagen zu 24 Stunden.

Warum das Schaltjahr und warum gab es keinen 10. Oktober 1582?

Grundsätzlich ist die Schaltjahrthematik mit obigem Wissen einfach zu verstehen. Damit sich die Jahreszeiten nicht verschieben, müßten wir ganz genau nach jedem tropischen Jahr ein neues Jahr beginnen. Das ist aber sehr ungeschickt, weil das tropische Jahr unabhängig von der Erdrotation ist, die uns einen mittleren Sonnentag von 24 Stunden beschert. So müßte ein Jahreswechsel mitten am Tag oder in der Nacht stattfinden und das wäre einfachen Kalenderregeln sehr abträglich. Andererseits hätten wir mit einem Jahreswechsel nach jeweils 365.0 Tagen bald das Problem, daß sich die Jahreszeiten im Kalender pro Jahr um einen viertel Tag verspäten würden. Eine Zeitdifferenz, die in kürzester Zeit die Jahreszeiten vom Kalender abweichen ließe. Im Jahre 46 vor Christus wurde dieses Problem mit Julius Cäsars Kalenderreform (Julianische Kalenderreform) halbwegs beseitigt. Auf drei Jahre mit 365 Tagen ließ man ein Schaltjahr mit 366 Tagen folgen. Damit hatte ein mittleres Kalenderjahr (365*3+366)/4=365.25 Tage und war jetzt um 11 Minuten länger als ein tropisches Jahr. Die erreichte Genauigkeit ist schon ganz gut, in nur 130 Jahren wächst die Zeitdifferenz aber trotzdem auf einen ganzen Tag an. Im 16. Jahrhundert waren daraus schließlich mehrere Tage geworden und weil sich das Osterdatum mehr und mehr verfrüht hatte, schaltete sich die Kirche mit einer Kalenderreform ein. Papst Gregor XIII ließ eine Kalenderreform durchführen, in der die angesammelte Zeitdifferenz wieder korrigiert und ein verfeinertes Schaltsystem eingeführt wurde, das bis heute gilt. Man ließ zur Korrektur der Zeitrechnung einfach zehn Tage ausfallen und so folgte auf den 4. Oktober 1582 direkt der 15. Oktober 1582. Die Schaltregel änderte sich folgendermaßen:

Schalttage gibt es in allen Jahren, deren Jahreszahl durch vier teilbar ist. Ausnahme: Ist die Jahreszahl durch 100 teilbar, wird kein Schalttag eingefügt, es sei denn die Jahreszahl ist durch 400 teilbar.

Alles klar? Z.B. war das Jahr 1900 kein Schaltjahr. Vier ist zwar Teiler von 1900, aber 1900 ist auch durch 100 teilbar und nicht durch 400. Das Jahr 2000 wird ein Schaltjahr sein: 2000 ist zwar durch 100 teilbar, aber auch durch 400.

Um die mittlere Jahreslänge einer Schaltperiode zu berechnen, nehmen wir die Gesamtzahl der Tage und dividieren durch 400. Drei Jahrhunderte mit jeweils 24 Schaltjahren und 76 normalen Jahren plus ein Jahrhundert mit 25 Schaltjahren und 75 normalen Jahren:

24*366+76*365=36524 für die Jahrhunderte, deren Jahreszahl durch 100 teilbar ist.
25*366+75*365=36525 für das Jahrhundert, dessen Jahreszahl durch 400 teilbar ist.
Insgesamt also 36524*3+36525=146097 Tage. 146087/400=365.2425

Die Abweichung vom tropischen Jahr beträgt also noch 365.2425-365.242198=0.000302 Tage. Das bürgerliche Jahr ist somit gegenüber dem tropischen Jahr um 26 Sekunden zu lang, was nur noch einem Fehler von 8e-5%=0.00008% entspricht! Die einfache Schaltregel ist schon sehr gut, wenn wir bedenken, daß wir damit die voneinander unabhängige Zeitdauer der Bewegung der Erde um die Sonne als Vielfaches der Erdrotation ausdrücken können. Leider wächst aber auch diese Differenz in 3300 Jahren auf einen ganzen Tag an. Durch Schaltminuten und Schaltsekunden lassen sich diese kleinen Zeitdifferenzen aber eliminieren.

Zeitdifferenzen auf dem Computer

Für den Computer suchen wir nun eine Funktion, die uns die Tage berechnet, die seit einem bestimmten Datum vergangen sind. Es gibt verschiedene Möglichkeiten dieses Problem zu behandeln und wie immer gilt, je kürzer der Algorithmus, desto unverständlicher ist er auch. Deshalb wählen wir hier einen etwas umständlicheren aber durchsichtigeren Weg.

Hier nun eine Funktion in OMIKRON.BASIC, die die Anzahl der vergangenen Tage seit dem 1.1.1991 bis zu einem angegebenen Datum ermittelt. Übergeben wird das Datum im rechnerüblichen und deutschen Format tt.mm.jj. Für jj >=91 ist 19jj, für alle anderen jj ist 20jj gemeint. Die Funktion an Zeiträume anzupassen, die außerhalb von 1.1.1991-31.12.2090 sind, sollte kein Problem sein. Die altmodischen Zeilennummern sind in OMIKRON.BASIC selbstverständlich nicht nötig, zur Referenzierung habe ich sie aber eingefügt:

1  DEF FN Tage(Kalenderdatum$)
2  3  LOCAL Tag,Monat,Jahr,I,Mt,Rest
4  RESTORE Mt
5  Rest=0
6  Tag= VAL( MID$(Kalenderdatum$,1,2))
7  Monat= VAL( MID$(Kalenderdatum$,4,2))
8  IF Monat>12 THEN
9     Monat=Monat MOD 12
10 ENDIF
11 IF VAL( MID$(Kalenderdatum$,7,2))<91 THEN
12    Jahr=2000+ VAL( MID$(Kalenderdatum$,7,2))
13 ELSE
14    Jahr=1900+ VAL( MID$(Kalenderdatum$,7,2))
15 ENDIF
16 FOR I=1 TO Monat-1
17    READ Mt
18    Rest=Rest+Mt
19    IF I=2 THEN
20       IF (Jahr MOD 4=0 AND Jahr MOD 100<>0) OR (Jahr MOD 400=0) THEN
21          Rest=Rest+1
22       ENDIF
23    ENDIF
24 NEXT I
25 Rest=Rest+Tag
26 FOR I=1991 TO Jahr-1
27    IF (I MOD 4=0 AND I MOD 100<>0) OR (I MOD 400=0) THEN
28       Rest=Rest+366
29    ELSE
30       Rest=Rest+365
31    ENDIF
32 NEXT I
33 Rest=Rest-1
34 RETURN Rest
35-Mt
36 DATA 31,28,31,30,31,30,31,31,30,31,30,31
37 END_FN

Erläuterungen

Variablen:
Kalenderdatum$ Übergebenes Datum im Format dd.mm.yy
Tag Tageszahl aus dem Datumsstring
Monat Monatszahl aus dem Datumsstring
Jahr volle Jahreszahl (z.B.: 1995 statt 95)
Rest Zählvariable für die Tage, die seit dem 01.01.91 vergangen sind

In Zeilen 5-15 wird das im deutschen Rechnerformat (dd.mm.yy) übergebene Datum in Tag, Monat und Jahr zerlegt. In Zeilen 16-24 werden die Tage des laufenden Jahres aufsummiert. Dies geschieht über die Summe der DATA-Zeilen. Nun wird sich mancher fragen, was bringt eine Funktion, die die Anzahl der Tage berechnet, die vom 01.01.91 bis zum Kalenderdatum$ vergangen sind, wenn man die Anzahl der zwischen zwei beliebigen Daten verstrichenen Tage berechnen möchte? Sehr viel sogar, denn diese ist einfach die Differenz der Funktionswerte von zwei Daten. Beispiel: Wieviel Tage sind ab dem 10.03.93 bis zum 15.06.95 vergangen? Das Ergebnis lautet:

Vergangen=FN Tage("15.06.95")-FN Tage("10.03.93")

Das "neuere" Datum muß dabei natürlich als erster Parameter angegeben werden, sonst erhält man eine negative Differenz. Als kleine Ergänzung nun noch eine Funktion, mit der man leicht den Wochentag zu einem Datum im Zeitraum zwischen 1.1.1991-31.12.2090 bestimmen kann. Sie benötigt die FN Tage(). Da sich glücklicherweise die Wochentage nach sieben Tagen immer wiederholen, braucht man nur den Wochentag eines beliebigen Referenzdatums zu kennen und kann über den Divisionsrest der seit dem 01.01.91 vergangenen Tage den Wochentag zu jedem beliebigen Datum bestimmen:

DEF FN Wochentag$(Datum$)
LOCAL Tage,Tag$
Tage=FN Tage(Datum$)
SELECT Tage MOD 7
CASE 0
   Tag$="Dienstag"
CASE 1
   Tag$="Mittwoch"
CASE 2
   Tag$="Donnerstag"
CASE 3
   Tag$="Freitag"
CASE 4
   Tag$="Samstag"
CASE 5
   Tag$="Sonntag"
CASE 6
   Tag$="Montag"
END_SELECT
RETURN Tag$
END_FN

Eine Schwachstelle hat die FN Tage() noch (und damit auch die Wochentags-Funktion): Es sind nur Daten möglich, die größer oder gleich dem 01.01.1991 und kleiner als der 31.12.2090 sind. Es dürfte aber kein Problem sein, die Funktion anzupassen an volle Jahreszahlen und nicht nur deren Zehnerstellen. Der Nachteil ist dann allerdings wieder, daß man nicht einfach das rechnerinterne Datumsformat übergeben kann.

Eine andere Möglichkeit zur Bestimmung der zwischen zwei Zeitpunkten vergangenen Zeit ist der Ansatz über das Julianische Datum. Beim Julianischen Datum werden einfach die ab einem bestimmten Datum vergangenen Tage gezählt. Der Nullpunkt der Zählung liegt bei 12 Uhr Weltzeit am 1.1.4713 v.Chr., d.h. immer um 12 Uhr Weltzeit beginnt ein neuer Tag nach dem Julianischen Datum. Die Uhrzeit wird als Tagesbruchteil in den Dezimalen angegeben. 18 Uhr UT am 01.12.1998 ist z.B. JD 2451149.25. Bei der Programmierung einer Funktion für das Julianische Datum müssen wir beachten, daß bürgerliche und astronomische Zeitrechnung nicht identisch sind. Astronomisch gibt es im Gegensatz zur bürgerlichen Zeitrechnung ein Jahr 0. Der bürgerliche Kalender richtet sich nach Christi Geburt, die man als Nullpunkt annimmt. Daher gibt es nur ein Jahr vor und ein Jahr nach Christus. Das astronomische Jahr 0 entspricht dem bürgerlichen Jahr 1 v.Chr., das astronomische Jahr -1 entspricht dem Jahr 2 v.Chr. usw. Nach der bürgerlichen Zeitrechnung hat also das erste Jahrtausend n.Chr. am 1.1.1 begonnen. Deshalb aufgepaßt! Wer wirklich den Zeitsprung ins dritte Jahrtausend feiern möchte, läßt die Sektkorken nicht schon an Neujahr 2000, sondern erst an Neujahr 2001 lauter knallen. Aber was soll's. Den Zahlensprung in Hunderter- und Tausenderstelle kann man ja auch als etwas besonderes feiern.

Die Funktion zur Berechnung des Julianischen Datums sieht

folgendermaßen aus:


1  DEF FN Juliandat!(Tag,Monat,Jahr,Ut!)
2  LOCAL Jd!,Y,M,B,Zeitraum
3  IF (Jahr<1582) OR (Jahr=1582 AND Monat<10) OR (Jahr=1582 AND Monat=10 AND Tag<5) THEN
4    Zeitraum=1'*** Julianischer Kalender
5  ELSE
6    IF Jahr=1582 AND Monat=10 AND Tag>4 AND Tag<15 THEN
7       Zeitraum=2
8    ENDIF
9  ENDIF
10 IF Jahr<>0 THEN
11    IF Zeitraum<>2 THEN
12       IF Jahr<0 THEN
13         Jahr+=1
14       ENDIF
15       IF Monat<=2 THEN
16          Y=Jahr-1
17          M=Monat+12
18       ELSE
19          Y=Jahr
20          M=Monat
21       ENDIF
22       IF Zeitraum=1 THEN
23          B=-2
24       ELSE
25          B=INT(Y/400)-INT(Y/100)
26       ENDIF
27       Jd!=INT(365.25!*Y)+INT(30.6!*(M+1))+B+1720996.5!+Tag+Ut!/24
28       IF Jd!<0 THEN '*** Julianisches Datum < 0 ist nicht definiert
29          Jd!=-3
30       ENDIF
31    ELSE
21       Jd!=-2
22    ENDIF
23 ELSE
24    Jd!=-1
25 ENDIF
26 RETURN Jd!
27 END_FN


Erläuterungen

Variablen:
Jahr Die Jahreszahl mit Tausenderstelle (jjjj)
Ut! Weltzeit in Stunden (14.30 Uhr = 14.5)
Jd! Das Julianische Datum

Zeilen 3-9: Unterscheidung, ob das übergebene Datum im Zeitraum vor der gregorianischen Kalenderreform, während den ausgefallenen Tagen, oder nach der gregorianischen Kalenderreform liegt. Wenn das Datum in den ausgefallenen Tagen liegt, wird als Fehler -2 zurückgegeben. Zeile 10: In der bürgerlichen Zeitrechnung gibt es kein Jahr 0, bei falscher Übergabe wird -1 als Fehler zurückgegeben. Zeilen 11-14: Korrektur von bürgerlicher auf astronomische Zeitrechnung. Zeilen 15-21: Der erste Monat eines Jahres wird intern als März verwaltet. Damit fällt der eventuelle Schalttag immer auf den letzten Tag des Jahres. Zeile 27: Jd! wird berechnet. Zeile 28: ein Julianisches Datum für einen Tag vor dem 1.1.4713 v.Chr. ist nicht definiert. Es wird als Fehler -3 zurückgegeben.

Die zwischen zwei Daten vergangene Zeit ist einfach die Differenz der zugehörigen Julianischen Daten, denn als Fixpunkt zählt das feste JD 0. Aus dem Julianischen Datum läßt sich einfach der Wochentag berechnen und zwar nicht nur für Tage in diesem Jahrhundert, sondern für alle Tage, für die das Julianische Datum definiert ist:

1 DEF FN Wochentag(Tag,Monat,Jahr)
2 T=FN Juliandat!(Tag,Monat,Jahr,12)
3 IF T>0 THEN
4    T=(T MOD 7)+1
5 ENDIF
6 RETURN T
7 END_FN

Jahr ist wieder im jjjj-Format angegeben. Die Funktion gibt die Nummer des Wochentages zurück: Mo=1, Di=2, ..., So=7.

Viel Spaß beim Ausprobieren und ein Prost am Jahrtausendwechsel, Neujahr 2001!


Literatur:

Sterne im Computer, K. Hempe, J Molt, ISBN 3-481-36411-3

Grundlagen der Ephemeridenrechnung, O. Montenbruck, ISBN 3-87973-913-7

Gerald Dietze 01/99


Letzte Änderung am 11.09.2000 durch astroman