Weiter zum Ihnhalt

Extra Tag, extra Bug: Schaltjahre in der Softwareentwicklung

14. Februar 2024

In unserer digitalisierten Welt, wo Daten und Zeitmessungen eine zentrale Rolle spielen, kann ein kleiner Berechnungsfehler zu grossen Problemen in Software- und IT-Systemen führen.

In einem Schaltjahr können Systeme anfälliger sein für solche Fehler, da der Kalender im Februar einen zusätzlichen Tag beinhaltet. Für uns Menschen scheint dies ein triviales Thema zu sein. Eine Maschine oder Software ist hier aber wesentlich unflexibler und setzt eine saubere Implementation in der Handhabung von Datumsdaten voraus.

Begleiten Sie uns auf diesem kurzen aber faszinierenden Exkurs, den wir dem Schaltjahr zu verdanken haben. Sollte am 29. Februar ein System nicht so funktionieren wie erwartet, so haben Sie bereits einen ersten Anhaltspunkt, was das Problem sein könnte. (Und ja, die nachfolgenden Bilder wurden mittels ChatGPT generiert.)

Was ist eigentlich genau ein Schaltjahr?

Dafür müssen wir ein bisschen ausholen:

Ein Jahr auf der Erde, also eine Umrundung um die Sonne in 360°, beträgt leicht mehr als 365 Tage, nämlich exakt 365 Tage, 5 Stunden, 48 Minuten und 45 Sekunden. Diese Zeitdauer wird auch als “tropisches Jahr” beschrieben. Um eine längerfristige Verschiebung der Jahreszeiten zu verhindern, wird alle paar Jahre am 29. Februar ein zusätzlicher Tag eingschoben. Grob erscheint der Schalttag alle vier Jahre im Kalender. Genau genommen gibt es die gregorianische Schalttag-Regelung. Diese besteht aus drei Regeln und definiert Schaltjahre folgendermassen:

1. Die durch 4 ganzzahlig teilbaren Jahre sind Schaltjahre, abgesehen von folgenden Ausnahmen:

2. Säkularjahre, also Jahre, die ein Jahrhundert abschliessen, sind keine Schaltjahre, abgesehen von folgender Ausnahme:

3. Säkularjahre die durch 400 ganzzahlig teilbar sind, gehören zu den Schaltjahren.

Demnach gehören die Jahre 1992 (1. Regel) sowie 1600 und 2000 (3. Regel) zu den Schaltjahren. Das Jahr 1900 (2. Regel), fällt aber nicht in die Kategorie eines Schaltjahres, weil es sich um ein Säkularjahr handelt, das nicht ganzzahlig durch 400 teilbar ist.

Nebst dem Schaltjahr gibt es auch noch weitere Korrekturen, wie die Schaltsekunde. Sie hilft, die koordinierte Weltzeit mit der tatsächlcihen Rotation der Erde zu synchronisieren. Auf diese wird in diesem Blog aber nicht weiter eingegangen, da sie mit dem Schaltjahr eigentlich nichts zu tun hat. Sie bringt aber ähnliche Konsequenzen mit sich und taucht ausserdem in unregelmässigen Abständen auf. Die letzte Schaltsekunde wurde übrigens am 1. Januar 2017 um 00:59:59 Uhr (Schweizer Zeit) eingefügt.

Wieso wird das Thema Schaltjahr aufgegriffen?

Für viele von uns ist der 29. Februar einfach ein weiterer Tag im Kalender wie jeder andere. Dies ist in einer Software leider nicht so simpel abzubilden und führt regelmässig zu Problemen und Systemausfällen, zu sogenannten Schaltjahr-Bugs.

Und nein, diese Vorfälle beschränken sich nicht auf kleine Firmen und deren Services. So übersprang die weitverbreitete Programmiersprache PHP den 29. Februar, wenn folgender Code Snippet zur Formatierung von Daten in der Software verwendet wurde: DateTime::createFromFormat. Dieser Bug wurde 2012 gemeldet und erst 2021 behoben.

Des weiteren kam es 2016 aufgrund eines Schaltjahr-Bug am Flughafen in Düsseldorf zu einem Ausfall der Gepäckförderbänder. Dabei wurden 1’200 Gepäckstücke nicht auf Flugzeuge verladen.

Auch Google und Microsoft hatten bereits mit Schaltjahren zu kämpfen. So wurde im Jahr 2012 für alle am 29. Februar abgespeicherten Chats auf Gmail fälschlicherweise das Datum 31. Dezember 1969 angezeigt. Im selben Jahr gingen bei Microsoft die Azure Services bereits am 28. Februar aufgrund eines Schaltjahr-Bugs offline.

Sie sehen, dieser zusätzliche Tag ist hat es in sich. Weitere Vorfälle finden Sie hier: https://codeofmatt.com/list-of-2020-leap-day-bugs/.

Wie bereits vor 4 Jahren werden auch dieses Jahr bestimmt neue Schaltjahr-Bugs auftauchen. Bleiben wir also gespannt.

Wie kommt es zum Schaltjahr-Bug?

Animal, Insect, Invertebrate

Im Gegensatz zu uns Menschen sind Maschinen mit einem zusätzlichen Tag Ende Februar definitiv weniger flexibel.

Je nach dem wie in der Software die Daten und Uhrzeiten gehandhabt werden, vor allem bei deren Berechnungen und Manipulationen, kann es schnell zu einem Bug kommen. Dabei ist die korrekte Berechnung von Schaltjahren grundlegend. Wird dies gar nicht oder auf falsche Weise implementiert, so kann dies, wie oben geschildert, zu erheblichen Systemfehlern führen. Beispielsweise könnte fälschlicherweise nur implementiert sein, dass alle Jahre, die ganzzahlig durch 4 teilbar sind, als Schaltjahre mit einem 29. Februar klassifiziert werden. Zugegeben, eine solche Implementierung würde in den nächsten 76 Jahren bis 2100 vermutlich problemlos funktionieren. Nichtsdestotrotz ist es eine falsche Handhabung, die potenziell zu Problemen führen kann.

Des Weiteren ist es möglich, dass bei einer Software eine konstante Länge von 365 Tage für ein Jahr angenommen wird. Gerade wenn (tägliche) Zinsen berechnet werden oder zeitlich festgelegte oder geplante Task ausgeführt werden sollen, kann es zu Komplikationen und im schlimmsten Fall zu einem Absturz kommen. Ebenfalls können Datum-Manipulationen Quellen für Bugs sein, vor allem wenn Schaltjahre dabei nicht in Betracht gezogen werden.

Als Beispiel: Hätte man am 1. März 2023 einen Task für in einem Jahr geplant, der ebenfalls wieder am 1. März laufen sollte und addiert somit ein Jahr bzw. 365 Tage zum alten Ausführungsdatum, so würde dies im 29. Februar resultieren. Umgekehrt würde man am 29. Februar einen Task auf in einem Jahr terminieren, so kann die Software bei falscher Implementation den Task auf den 29. Februar 2025 zu setzen – ein Datum, das es in Wirklichkeit gar nie geben wird. Dies sind nur einige Beispiele, wie es zu einem Schaltjahr-Bug kommen kann.

Wie verhindern wir einen Schaltjahr-Bug?

Eine komplette Absicherung gegen den Schaltjahr-Bug ist zwar möglich, aber schwer zu erreichen und je nach Software auch gar nicht nötig. Eine korrekte Implementierung eines Schaltjahr-Algorithmus ist bereits ein grosser und wichtiger Schritt. Dieser muss dabei die drei oben beschriebenen Schalttags-Reglungen beinhalten.

Darüber hinaus sind robuste Programmiertechniken sowie extensives Testing nötig, um sicherzustellen, dass die Datenhandhabung korrekt funktioniert.

Wird eine API verwendet, um Daten zu manipulieren, so ist es wichtig zu wissen, wie diese Schnittstelle solche Manipulationen und Schaltjahre handhabt.

Planen Sie eine Applikation oder ein Webtool und möchten sichergehen, dass keine ungewollten (Schaltjahr-)Bugs auftauchen, dann setzen Sie sich mit uns in Verbindung.