Tipps & Tricks - Velocity Datums-API

Dieser Beitrag zeigt, wie Datumsberechnungen in Intrexx mit Velocity schnell und einfach ausgeführt werden können. Intrexx stellt für solche Zwecke das Objekt $DtUtil zur Verfügung. Wir zeigen Ihnen hier einige Einsatzszenarien und Beispielberechnungen. Vorkenntnisse in Velocity, JavaScript und Java sind für diesen Beitrag von Vorteil.

Die gesamte Java-API-Dokumentation finden Sie hier.

Mit $DtUtil können Datumswerte erzeugt werden. Dazu gehören das aktuelle Datum, Datumswerte mit spezifischen Anpassungen für Jahr, Monat, Tag etc. sowie das Parsen von Datumswerten aus Strings oder feiertagsspezifische Daten wie Karfreitag. Die Zählung der Monate beginnt, wie in Java und JavaScript üblich, bei 0. Dies bedeutet: 0 spezifiziert Januar, 1 spezifiziert Februar, usw. Das API verwendet nachsichtige (lenient) Kalender, d.h. Überläufe oder Unterläufe von Datumsfeldern (Monat, Tag, Stunde, Minute, Sekunde, Millisekunde) führen nicht zu Exceptions. Beispiel:

#set($date = $DtUtil.date(2018,3,0,$User.getTimeZone()))

Der im Aufruf fehlerhafte Wert 0. April 2018 führt zu dem Ergebnis 31.03.2018.

Aktuelles Datum erzeugen

Erzeugen eines aktuellen Datums anhand der übergebenen Zeitzone, in diesem Beispiel mit der des aktuell an einem Portal angemeldeten Benutzers:

#set($now = $DtUtil.now($User.getTimeZone()))

Beliebiges Datum erzeugen

Erzeugen eines beliebigen Datums anhand der übergebenen Zeitzone. Die verwendete Methode date() kann mit einer unterschiedlichen Anzahl von Parametern aufgerufen werden. So kann ein Datum erzeugt werden, bei dem nur das gewünschte Jahr angegeben wird und die restlichen Werte wie Monat, Tag, etc. auf Initialwerte (01. Januar, Zeitwerte auf 0) gesetzt werden. Alternativ kann date() z.B. mit allen setzbaren Parametern, angefangen vom Jahr bis zu Millisekunden, aufgerufen werden. Genauere Details sind der Java-Dokumentation zu entnehmen.

Neues Datum mit Angabe des gewünschten Jahres:

#set($date = $DtUtil.date(2000, $User.getTimeZone()))

Das Ergebnis ist ein neues Datumsobjekt mit dem Wert 2000-01-01 00:00:00.0. Neues Datum mit Angabe von Jahr, Monat, Tag und Stunde:

#set($date = $DtUtil.date(2012, 1, 29, 18, $User.getTimeZone()))

Das Ergebnis ist ein neues Datumsobjekt mit dem Wert 2012-02-29 18:00:00.0.

Zeitzonen

Ein wichtiger Punkt bei Datumsberechnungen ist die dem Datum zugrunde liegende Zeitzone. Im Intrexx-Umfeld kann man auf verschiedene Zeitzonen treffen. Die Basis bildet die Zeitzone des Servers, auf dem der Portaldienst läuft. Für Datenbank-Operationen kann es u.U. eine eigene Datenbankzeitzone geben. Dies ist abhängig von der Konfiguration der verwendeten Datenbank. Weiter können einzelnen Intrexx-Benutzern persönliche Zeitzoneneinstellungen zugewiesen werden. In wieweit die Zeitzone bei den Datumsoperationen eine Rolle spielt, hängt von dem jeweiligen Anwendungsfall ab und kann nicht verallgemeinert werden. Ein Anwendungsfall besteht z.B. darin, den aktuellen Zeitstempel in die Datenbank zu speichern. In diesem Fall ist die Übergabe der Zeitzone nicht zwingend erforderlich. Sollen jedoch z.B. Datumswerte angezeigt oder berechnet werden, muss die jeweilige Zeitzone des Betrachters berücksichtigt werden, um eine fehlerfreie Darstellung zu gewährleisten. Finden auf einer Seite bzw. innerhalb eines Skripts mehrere Datumsoperationen mit Zeitzonen statt, ist es sinnvoll, am Anfang des Skripts eine Hilfsvariable $tz zu definieren und dieser die zu verwendende Zeitzone zuzuweisen.

#set($tz = $User.getTimeZone())
#set($dtDate1 = $DtUtil.date(2000, $tz))
#set($dtDate2 = $DtUtil.date(2001, 8, $tz))

CalendarAwareDate und R-Methodensuffixe

Wird über $DtUtil ein neues Datum erzeugt, erhalten Sie als Rückgabe ein Objekt der Klasse CalendarAwareDate. Die Klasse leitet von java.sql.Timestamp und somit auch von java.util.Date sowie von IDateTimeValueHolder ab, d.h. alle dort verfügbaren Methoden sind auch auf CalendarAwareDate-Objekte anwendbar. Es ist der Java-Dokumentation zu entnehmen, dass für jede Methode eine analoge Methode mit dem Suffix R existiert, beispielsweise addDays(int p_iDays) und addDaysR(int p_iDays). Die Methoden unterscheiden sich in ihren jeweiligen Rückgabewerten. Methoden ohne R-Suffix liefern das Datum, auf das die Methode angewandt wurde, nicht zurück, sondern verwendet den Rückgabetyp void. Bei Methoden mit Suffix wird das Objekt selbst zurückgeliefert. Hierdurch sind Verkettungen von Methodenaufrufen möglich, womit Definitionen von Hilfsvariablen gespart werden können und somit ein Aufblähen des Codes verhindert werden kann.

#set($dtNow = $DtUtil.now($User.getTimeZone()))
$dtNow.addYears(1)
$dtNow.addMonths(6)
$dtNow.addDays(10)
#set($dtNew = $dtNow)

Mit R-Suffix:

#set($now = $DtUtil.now($User.getTimeZone()))
#set($dtNew = $now.addYearsR(1).addMonthsR(6).addDaysR(10))

Datumsberechnungen

Wie im vorigen Kapitel bereits gezeigt, existieren für CalendarAwareDate-Objekte diverse Methoden zur Datumsberechnung wie Addition und Subtraktion. Es existieren zu allen Datumseigenschaften (Jahr, Monat usw.) analoge Methoden für Addition und Substraktion. Als Ergänzung zu den im Vorfeld beschriebenen Methoden mit R-Suffix gibt es außerdem auch noch Methoden, bei denen die Zeitzone UTC Bestandteil des Namens ist. Für die Addition einer Anzahl an Jahren existieren z.B. folgende Methoden:

  • addYears(int p_iYears)

  • addYearsR(int p_iYears)

  • addUTCYears(int p_iYears)

  • addUTCYearsR(int p_iYears)

Erklärung:

addYears(int p_iYears)
Addiert p_iYears Jahre auf ein bestehendes Datum unter Berücksichtigung der Zeitzone des bestehenden Datums ohne einen Rückgabewert.

addYearsR(int p_iYears)
Addiert p_iYears auf ein bestehendes Datum unter Berücksichtigung der Zeitzone des bestehenden Datums und liefert das manipulierte Objekt als Rückgabewert zurück.

addUTCYears(int p_iYears)
Addiert p_iYears auf ein bestehendes Datum in der UTC-Zeitzone ohne einen Rückgabewert.

addUTCYearsR(int p_iYears)
Addiert p_iYears auf ein bestehendes Datum in der UTC-Zeitzone und liefert das manipulierte Objekt als Rückgabewert zurück.

Datumsliterale für JavaScript

Mit $DtUtil ist es auch möglich, Datumsliterale so aufzubereiten, so dass diese anschließend an eine JavaScript-Funktion übergeben und so weitere clientseitige Berechnungen durchgeführt werden können. Mit dem Velocity-Skript

#set($date = $DtUtil.now($User.getTimeZone()))
$DtUtil.dateToISOString($date)

kann das aktuelle Datum als ISO-String für JavaScript (nach ECMAScript Language Specification) aufbereitet und anschließend in JavaScript verwendet werden, wie im folgenden Skript gezeigt. Im Aufruf getElement("GUID") ist die GUID eines Textfeldes (statischer Text) einzufügen, in dem sich das aufbereitete ISO-Datum aus Velocity befindet.

function alertJsDate()
{
   var dtNowJS = Browser.getValue(getElement("9661....3FA9"));
   alert(new Date(dtNowJS));
   return true;
}

Weitere Methoden

Neben den hier beschriebenen Methoden existieren zahlreiche weitere Methoden, die bei der Umsetzung anderer Anwendungsfälle helfen können, wie z.B. Feiertagsberechnungen, das Parsen von Datumsliteralen und Datumsvergleiche. Beachten Sie dazu die Java-Dokumentation der Klassen DateTimeUtil und CalendarAwareDate.