Tagesarchiv für den 14. September 2007

Zeitzonen

Freitag, den 14. September 2007

Unsere Verwaltungssoftware hat nun ein weiteres kleines, aber feines Feature: die Unterstützung von Zeitzonen. Um ausländischen Kunden die Anzeige zu erleichtern, werden intern alle Uhrzeiten in GMT/UTC abgespeichert und während der Anzeige an die jeweilige Zeitzone des Kunden angepasst.

Die ursprüngliche Idee war, im Kundenprofil jeweils nur die entsprechenden GMT-Offset-Stunden zu speichern (z.B. “2″ für GMT+2). Wenn da nicht so Länder wie Nepal wären, die als GMT-Offset 5:45 Stunden haben… :-) In diesem Fall speichern wir das also in Minuten (es gibt auch sekundengenaue Zonenwechsel im Rahmen der jeweiligen Angleichung an GMT, aber uns interessieren eh erst Zeiten ab dem Computer-Urknall am 01.01.1970).
Das nächste Problem sind die Sommerzeiten. Dafür gibt es keine feste Regelung; die einen Länder schaffen die Sommerzeit gerade spontan ab, andere orientieren sich am Ramadan, andere haben wiederum gesetzlich festgelegt daß der Sommer mindestens 150 Tage lang sein muß, und so weiter… Wir könnten nun zusätzliche Eingabemasken definieren, mit denen die Kunden das selber pflegen können, aber zum einen wird das auf Dauer lästig (und Fehleranfällig), zum anderen möchten wir auch in zehn Jahren noch wissen wann dieses Jahr die Sommerzeit angefangen hat (die Daten müssten also historisch gespeichert werden, was das Ganze auch nochmal komplexer macht).

Also wurde das Ganze gleich ganz ordentlich gemacht: mit der frei verfügbaren Zeitzonen-Datenbank, die u.a. auch Basis für die GNU glibc ist. In einigen großen Textdateien sind (fast?) alle Zeitzonen sowie deren Regeln definiert.

Ein kompaktes Perl-Script (immerhin auch 300 Zeilen) parst diese Dateien, filtert nur Regeln ab dem 01.01.1970 heraus, und schreibt das in SQL-Befehle um, mit denen wiederum die Backend-Datenbank gefüttert wird.

Daraus wird dann beim Laden des Benutzerprofils (z.B. beim Login) die gewünschte Zeitzone und alle relevanten Regeln in eine spezielle Datenstruktur im Speicher geladen (sind nur wenige Byte). Die Datums-Klasse (C++) konvertiert dann mit einem Befehl eine GMT-Zeitangabe in die gewünschte Zeitzone um und stellt daneben auch das jeweils gültige Zeitzonen-Kürzel (z.B. “CEST”) bereit. Der Overhead ist somit absolut minimal.

Und so schaut’s dann aus, wenn ich meine Zeit auf Nepal einstelle… ;-)

npt.gif