Zeitrechnung

von Hubert Schmid vom 2014-04-06

Das große Problem mit der Zeitrechnung innerhalb von Programmen ist, dass intuitives Verständnis dabei sehr irreführend sein kann. Ein kleiner Test soll diese Behauptung untermauern. Die Frage ist, welche der drei folgenden Aussagen richtig ist?

  1. Der Tag ist 24 Stunden lang.
  2. Der Tag beginnt um 0:00 Uhr.
  3. Auf den Donnerstag folgt der Freitag.

Tageslicht sparende Zeit

Dass die erste Aussage falsch ist, wird uns in Deutschland mindestens zweimal im Jahr zu Bewusstsein geführt – zuletzt am 30. März 2014 mit der Umstellung auf die Mitteleuropäische Sommerzeit. Durch das Vorstellen der Uhr von 02:00 auf 03:00 wird eine Stunde übersprungen, so dass der Tag nur 23 statt 24 Stunden umfasst. In Java 8 lässt sich das mit der Bibliothek java.time einfach nachvollziehen, wie im folgenden Listing zu sehen.

ZonedDateTime date = LocalDate.of(2014, Month.MARCH, 30) .atStartOfDay(ZoneId.of("Europe/Berlin")); System.out.println(date.until(date.plusDays(1), ChronoUnit.HOURS));

Das Programm gibt korrekt 23 aus. Ändert man das Datum auf den 26. Oktober 2014 – das Ende der Sommerzeit – gibt das Programm korrekt 25 aus. Weder in der Realität noch in der Java-Bibliothek entspricht also ein Tag der Dauer von 24 Stunden. Die Java-Bibliothek macht diese Unterscheidung sogar explizit, indem sie nach Datums-basierter und Zeit-basierter Dauer trennt (Period und Duration).

Wer hat an der Uhr gedreht?

Warum wird bei der Umstellung von Winter- auf Sommerzeit die Uhr eigentlich von 02:00 auf 03:00 vorstellt, statt von 23:30 auf 0:30? Vermutlich weil so spät nachts für die meisten Leute die konkrete Uhrzeit um Unbedeutendsten ist. Doch auch abgesehen von Umstellung zwischen Winter- und Sommerzeit wird gelegentlich an der Uhr gedreht. Ein Beispiel dafür zeigt folgendes Listing.

ZonedDateTime date = LocalDate.of(1986, Month.JANUARY, 1) .atStartOfDay(ZoneId.of("Asia/Kathmandu")); System.out.printf("%tR\n", date);

Die beiden Anweisungen geben die Uhrzeit aus, mit der Neujahr 1986 in Nepal begann. Die Ausgabe ist 00:15 und nicht wie man vielleicht annehmen würde 00:00. Das ist auch korrekt so, denn tatsächlich wurde die Uhr an diesem Tag einmalig vorstellt. Die Annahme, dass ein Tag grundsätzlich um 0:00 Uhr begänne, ist also falsch.

Verschwundener Tag

Am Donnerstag Abend ins Bett gehen und erst am Samstag wieder aufstehen. Das ist 2011 den rund 200 000 Einwohnern von Samoa passiert. Auch das lässt sich mit Java 8 und der Bibliothek java.time einfach nachvollziehen.

ZonedDateTime date = LocalDate.of(2011, Month.DECEMBER, 29) .atStartOfDay(ZoneId.of("Pacific/Apia")); System.out.println(date.getDayOfWeek() + "-" + date.plusDays(1).getDayOfWeek());

Das Programm gibt THURSDAY-SATURDAY aus. Also folgte auf Donnerstag, den 29.12.2011, kein Freitag sondern ein Samstag. Tatsächlich war es der 31. Dezember, der auf den 29. Dezember folgte. Der 30. Dezember wurde einfach ausgelassen. Was merkwürdig klingt, hat einen einfachen Hintergrund: Samoa wechselte zu diesem Zeitpunkt auf die andere Seite der Datumsgrenze.

Die Annahme, dass auf Wochentage verlass wäre, ist also ebenfalls falsch. Was bleibt ist die Erkenntnis, dass Datums- und Zeitrechnung im Detail nicht so einfach ist, wie es zunächst aussieht. In der Softwareentwicklung ist es daher umso wichtiger, sich frühzeitig mit dem Thema auseinanderzusetzen – vor allem im Rahmen der Internationalisierung. So steht man der sicheren Seite, insbesondere falls mal wieder jemand an der Uhr dreht.