Montag, 21. Februar 2011

Praktische Datums-Helferlein

Spätestens seit dem weitgehend ausgefallenen Jahr-2000-Problem und dem dann überraschend eingetretenen Jahr-2010-Problem weiß es jeder: Das Hantieren mit Datum-Werten in Software ist widerlich und extrem fehleranfällig(*). Der tiefere Grund liegt im Datums- und Zeit-Format: Das ist aus Software-Entwickler-Sicht geradezu schwachsinnig un-orthogonal und schrecklich. Die Einheiten (Tage, Wochen, Monate, Jahre) hängen nicht wohl-definiert und dezimal zusammen, wie das praktisch wäre. Für Monate (28,29,30 oder 31 Tage) und Jahre (365 und 366 Tage, und wann nochmal gleich?) gibt es noch nicht mal feste Bezugspunkte. Haufenweise Gelegenheiten also, Fehler zu machen. Nun werden wir am grundsätzlichen Problem so schnell nichts geändert kriegen. Der Mensch als Erdenbewohner hat es nunmal gern wenn sich seine Zeitmaße an den unrunden Zeiträumen seiner natürlichen Umgebung ausrichten (Tages- und Jahreszeiten). Daher bleibt uns nur, auf Software zu hoffen, die uns bei dieser undankbaren Aufgabe hilft.

Daher ist es recht praktisch, dass uns Rails mit einer extrem wohl sortierten Sammlung von Helferlein bei diesem unangehmen Thema unter die Arme greift. Das tut es wie üblich per Erweiterung (Monkey-Patching) der Core-Classen Date, DateTime und Time (der Code ist in der Klasse ActiveSupport::CoreExtensions::DateTime::Calculations). Am besten eignet sich die Rails Console, um sich einen Überblick zu verschaffen. Ein paar Beispiele für schwierige Dinge, die damit einfach gehen:


andi@xwing:~/lc-search-ana$ ./script/console
Loading development environment (Rails 2.3.10)

# Heute:
>> Date.today
=> Mon, 21 Feb 2011

# Gut das ist noch nicht so spannend. Anfang dieser Woche:
>> Date.today.end_of_week
=> Sun, 27 Feb 2011

# Montag in 4 Wochen:
>> Date.today.beginning_of_week.advance(:weeks => 4)
=> Mon, 21 Mar 2011

# Ende des Monats Januar
>> Date.today.beginning_of_year.end_of_month
=> Mon, 31 Jan 2011

# Ein Monat später als 31. Januar ist *28*. Februar
>> Date.today.beginning_of_year.end_of_month.advance(:months => 1)
=> Mon, 28 Feb 2011



Besonders gut gefällt mir dabei, wie leserlich die Operationen hier aneinander reihen lassen. Wer die Java-Calendar-Classen kennt, weiß das diese ähnliche Operationen bieten. Trotzdem vertut man sich dort aufgrund des komplizierten Syntax immer mal wieder. Hier lässt sich die Konstruktion des Datums als englischer Text ablesen. Fein!



* Und wir lassen jetzt die Komplexität der Tageszeiten mit ihren unterschiedlichen Zeitzonen mal außen vor!

Keine Kommentare:

Kommentar veröffentlichen