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.