Gestern, heute, morgen - Datumsarithmetik im DB2

DB2 besitzt eine Reihe von Funktionen, die für Datumsberechnungen verwendet werden können. Ähnliche Funktionen gibt es auch für Uhrzeitberechnungen, jedoch werden diese nicht so oft Verwendung finden.
Für die Speicherung und Verarbeitung eine Datums gibt es im DB2 das spezielle Format Date. Datumsarithmetik läßt sich nur dann nutzen, wenn das Datum in diesem Format vorliegt (Hostvariablen müssen ggf. mit der skalaren Funktion Date () umgewandelt werden). Analog gilt für die Uhrzeit das interne Format time und die skalare Funktion time(). Für ganz exakte Zeitstempel gibt es noch das Format timestamp, das Datum und Uhrzeit auf die Mikrosekunde genau speichert.

Das Spezialregister current date

Das Spezialregister current date beinhaltet das aktuelle Datum und ist nahezu universell einsetzbar. Beispiele:

INSERT INTO tabelle ( sp1,sp2,sp3 ) VALUES ( current date , :host2 , :host3 ) ;

SELECT sp1,sp2,current date FROM tabelle ...;

UPDATE ... SET sp1 = current date WHERE ...;

SELECT ... WHERE sp1 < current date

Set :host = current date ;

analog existieren auch die Spezialregister current time und current timestamp

Datumsarithmetik

Die einfachste Form der Datumsarithmetik besteht darin, zu einem Datum eine bestimmte Zeitspanne zu addieren oder zu subtrahieren. DB2 erlaubt, Tage, Monate , Jahre sowie eine Kombination daraus zu addieren/subtrahieren. Dies ist überall dort erlaubt, wo im SQL-Statement ein normaler Ausdruck stehen darf. Der Ergebnistyp ist wieder Date.
Beispiele:
Set :host1 = Date (:host2) + 1 Year + 5 Month + 10 Day ;
( in der Hostvariable host2 muss hier natürlich ein gültiges Datum stehen . host1 enthält dann das Datum, das 1 Jahr 5 Monate und 10 Tage nach host2 liegt )

Select ... Where sp1 > current date - 1 Month ;

Selbstverständlich können auch Hostvariablen als Zeitspanne verwendet werden:

Set :datneu = Date (:datalt) + :n Year - :m Day;

Als Zeitspanne ist dabei möglich:

für ein Datum:
- Tage ( day )
- Monate ( month )
- Jahre ( year )

für eine Uhrzeit:
- Stunden ( hour )
- Minuten ( minute )
- Sekunden ( second )

für einen Timestamp zusätzlich zu den obigen:
- Mikrosekunden ( microsecond )

grundsätzlich erlaubt DB2 auch die Pluralformen ( also days , months , years usw. )

Wird durch eine Addition oder Subtraktion von Monaten oder Jahren ein Monatsende überschritten, so gleicht DB2 das Ergebnis automatisch an. Ein '31.01.2001' + 1 Month würde eigentlich den 31.02.2001 ergeben, DB2 gibt hier den Monatsletzten ( '28.02.2001' ) zurück

Die Date - Duration

Das ist eine Besonderheit im DB2. Sie ist das Ergebnis einer Subtraktion zweier Date-Felder. Ihre externe Darstellung ist eine Decimal(8) - Zahl, bestehend aus JJJJMMTT (positionsgerecht).
( Hinweis: Im PL/1 sollten bei Decimalvariablen keine geraden Stellenanzahlen verwendet werden, da sie den Compiler zu "Umwegen" zwingen können. DB2 toleriert auch ein DECIMAL(9) - Feld. )

Beispiel:
Date ( '17.03.2003') - Date ('08.01.1999') ergibt die Dezimalzahl 40209
( die Differenz ist 4 Jahre, 2 Monate, 9 Tage ).
Eine Date-Duration kann ihrerseits zu einem Datum addiert oder davon subtrahiert werden und ergibt wieder ein neues Datum.

skalare Funktionen in Verbindung mit Datumsarithmetik

ADD_MONTH ( datum , numerisch )Addiert Monate zu einem Datum oder Timestamp. Ein Monatsletzter wird automatisch wieder zum Monatsletzten. Das unterscheidet diese Funktion von der normalen Datumsarithmetik. ein '28.02.2001' + 1 month ergibt den "28.03.2001", die Funktion ADD_MONTH erkennt den Monatsultimo und ADD_MONTH('28.02.2001',1) ergibt den "31.03.2001".
CHAR(datum,format)Formatiert das Datum gemäss dem vorgegebenen Format: möglich ist die Vorgabe von
EUR = tt.mm.jjjj
ISO = jjjj-mm-tt
JIS = japanischer Standard
USA = mm/tt/jjjj
LOCAL = lokaler default
(keine Vorgabe) = installations-default
ADD_DAYS(ausdruck,integer)Addiert integer Tage zum vorgegebenen Wert (kann DATE oder TIMESTAMP ohne TIMEZONE sein. Diese Funktion ist nur bei aktivem acceleration server als passthrough-only verfügbar)
DATE(char)Verwandelt einen Charakter-string in das Datumsformat
DAY(ausdruck)extrahiert den Tag aus einem Datum oder timestamp. Beinhaltet der ausdruck eine timezone, wird vorher in UTC umgerechnet
DAYOFMONTH(datum)Gibt den Tag (1-31) des datums zurück
DAYOFWEEK(datum)Gibt den Wochentag zurück ( 1 = Sonntag, 2 = Montag ... 7 = Samstag ).
DAYOFWEEK_ISO(datum)Gibt den Wochentag zurück ( 1 = Montag, 2 = Dienstag ... 7 = Sonntag ).
In den USA beginnt die Woche am Sonntag, die europäischen Normen ISO (und die deutsche DIN) definieren als Wochenbeginn den Montag, daher gibt es unterschiedliche Funktionen )
DAYOFYEAR(datum)ermittelt den relativen Tag innerhalb des Jahres ( 1 - 366 )
DAYS(datum)gibt die Anzahl der Tage seit dem '01.01.0001' zurück
DAYS_BETWEEN(ausdruck1,ausdruck2)gibt die Anzahl der kompletten Tage zwischen ausdruck1 und ausdruck2 zurück. ausdruck1/2 kann date oder timestamp ohne timezone sein. Das Ergebnis kann positiv oder negativ sein. Diese Funktion ist nur bei aktivem acceleration server als passthrough-only verfügbar
EXTRACT ( teil FROM datum/uhrzeit ) Extrahiert den angegebenen Teil aus datum, uhrzeit oder timestamp.
teil kann sein YEAR, MONTH, DAY, HOUR, MINUTE oder SECOND.
Ist eine Zusammenfassung der Funktionen YEAR(), MONTH(), DAY(), HOUR(), MINUTE() und SECOND()
HOUR(uhrzeit)gibt die Stunden einer Uhrzeit zurück
JULIAN_DAY(datum)gibt den relativen Tag gemäss julianischem Kalender zurück. ( Anzahl Tage seit dem '01.01.4712' v.Chr.)
LAST_DAY(datum)gibt den Monatsletzten ( 28 - 31 ) des vorgegebenen Datums zurück.
MICROSECOND(timestamp)gibt die Microsekunden eines Zeitstempels zurück
MIDNICGHT_SECONDS(uhrzeit)ermittelt die Anzahl Sekunden seit Mitternacht ( 0 - 86400 )
MINUTE(uhrzeit)gibt die Minuten einer Uhrzeit zurück
MONTH(datum)extrahiert den Monat aus einem Datum
MONTHS_BETWEEN ( datum1,datum2 )gibt die Zeitdifferenz zwischen datum1 und datum2 in Monaten zurück ( als DESIMAL(31,15). Ein Tag sind genau 0.032258064516129 Monate )
NEXT_DAY(datum,vorgabe)ermittelt den nächsten Tag nach datum, der der Vorgabe entspricht. vorgabe kann sein: SUN ( für Sonntag - sunday ) bis SAT ( für Samstag - saturday ). Der Wochentag kann auch ausgeschrieben werden ). Das Ergebnis ist immer ein Timestamp - ggf mit Uhrzeit 00:00:00 !
QUARTER(datum)Ermittelt das Quartal ( 1-4 ) in dem das Datum liegt
ROUND_TIMESTAMP(timestamp,format)erlaubt das Runden eines Zeitstempels. format kann sein
CC - Runden auf Jahrhundert
YEAR - Runden aufs Jahr
Q - Runden aufs Quartal
MONTH - Runden aufs Monat
DD - Runen auf den Tag
HH - Runden auf die Stunde
MI - Runden auf die Minute
SS - Runden auf die Sekunde
es sind einige weitere Formate möglich. siehe SQL-Reference
SECOND(uhrzeit)gibt die Sekunden einer Uhrzeit zurück
TIME(ausdruck)verwandelt den Ausdruck in eine Uhrzeit
TIMESTAMP(ausdruck)verwandelt den Ausdruck in einen Zeitstempel
TIMESTAMP(datum,uhrzeit)Kombiniert Datum und uhrzeit zu einem Zeitstempel
TIMESTAMPADD(numerisch1,numerisch2,timestamp)Addiert bestimmte Werte zu einem Timestamp.
numerisch1 gibt an, was addiert werden soll
1 Microseconds
2 Seconds
4 Minutes
8 Hours
16 Days
32 Weeks
64 Months
128 Quarters
256 Years
numerisch2 gibt an, wieviel addiert werden soll
TIMESTAMP_ISO(datum oder uhrzeit) Wandelt ein vorgegebenes Datum oder eine Uhrzeit in einen Zeitstempel um. Ein Datum wird mit 00:00:00 Uhr ergänzt, eine Uhrzeit mit dem Tagesdatum ( CURRENT DATE )
TRUNC_TIMESTAMP(timestamp,format)verringert die Genauigkeit eines Zeitstempels. format entspricht dabei weitgehend den Werten von ROUND_TIMESTAMP, nur dass nicht gerundet, sondern abgeschnitten wird.
VARCHAR(datum,format)Konvertiert das Datum zu einem VARCHAR-Feld, das Format der Konvertierung entspricht dem der CHAR Funktion
WEEK(date)Ermittelt die relative Woche innerhalb des Jahres (nach amerikanischem Standard)
WEEK_ISO(date)Ermittelt die relative Woche innerhalb des Jahres (nach europäischem Standard).
( Woche 1 nach amerikanischem Standard ist die Woche, die den 1. Januar enthält - nach europäschem Standard ist es die Woche, die den ersten Donnerstag des Jahres enthält. Ausserdem beginnt nach amerikanischem Standard die Woche am Sonntag, nach europäschem Standard am Montag)
YEAR(datum)Extrahiert das Jahr aus einem Datum


datum ist dabei ein DATE, ein TIMESTAMP, ein Characterstring, der als Datum interpretierbar ist oder eine arithmetische Operation, die ein DATE erzeugt hat.
uhrzeit ist analog eine TIME, ein TIMESTAMP, ein Characterstring, der als Uhrzeit interpretierbar ist oder eine arithmatische Operation, die eine TIME erzeugt hat.

Datum und Uhrzeit im Lade-Utility

In früheren Versionen kannte DB2 nur vier verschiedene Formate für Datum und Uhrzeit: ISO-Standard (ISO), US-Standard (US), Europäischer Standard (EUR), Japanischer Industrie Standard (JIS), dazu kam noch ein benutzerdefinierter Standard (LOCAL).

Beginnend mit Version 12 kann das LOAD UTILITY einige weitere Darstellungsformen von Datum und Uhrzeit interpretieren.
Das entsprechende Format muss dabei in der Ladekontrollkarte angegeben werden.

LOAD ... INTO TABLE …
feld POS ( x:y ) DATE EXTERNAL ( format )

Diese Formate können derzeit verwendet werden:

Formatentspricht der Darstellung
DATE_Amm-tt-jjjj
DATE_Bmm-tt-jj
DATE_Cjjjj-mm-tt
DATE_Djj-mm-tt
DATE_Ett-mm-jjjj
DATE_Ftt-mm-jj
DATE_Gjjjj-ttt
DATE_Hjj-ttt
DATE_Immttjjjj
DATE_Jmmttjj
DATE_Kjjjjmmtt
DATE_Ljjmmtt
DATE_Mttmmjjjj
DATE_Nttmmjj
DATE_Ojjjjttt
DATE_Pjjttt
TIME_Ahh.mm.ss
TIME_Bhh.mm
TIME_Chh.mm AM oder PM
TIME_Dhhmmss
TIME_Ehhmm
TIMESTAMP_Ajjjj-mm-tt-hh.mm.ss
TIMESTAMP_Bjjjj-mm-tt-hh.mm.ss.nnnnnn
TIMESTAMP_Cjjjjmmtthhmms
TIMESTAMP_Djjmmtthhmmss
TIMESTAMP_Ejjjjmmtthhmmssnnnnnn
TIMESTAMP_Fjjmmtthhmmssnnnnnn

Wird das Jahr nur zweistellig angegeben, dann wird es von DB2 automatisch auf vier Stellen erweitert. Dazu wird der Wert mit dem aktuellen Jahr verglichen. Ist die Differenz 50 oder mehr, dann wird das Jahr zu 19xx, sonst zu 20xx.
Beispiel:
Ein DATE_B von '10-15-70' würde ( aktuelles Jahr 2018: Berechnung also 70-18 = 52. Differenz ist 50 oder mehr ) zum 15.10.1970 umgewandelt werden, ein '02-08-33' würde ( da 33-18 < 50 ) zum 08.02.2033


Zurück zu DB2 Home Impressum / Datenschutz