Datumswerte mit und ohne Zeitangabe vergleichen

15.06.2006 von Helma  Spona
Datumswerte haben so ihre Tücken. Es gibt zig verschiedene Datumsformate und damit auch Eingabemöglichkeiten. Versuchen Sie dann, innerhalb von Abfragen Datensätze mit bestimmten Datumswerten zu suchen, machen Ihnen gerade diese Datumsformate zu schaffen. Wo genau die Schwierigkeiten liegen und wie Sie effiziente Datumsvergleiche durchführen, zeigt dieser Beitrag.

Anders als bei numerischen Tabellenfeldern, bei denen Sie neben dem Datentyp Zahl auch die Größe des Feldes und damit den genauen Unterdatentyp festlegen können, kennt Access bei Datumsfeldern nur den Datentyp Datum/Uhrzeit. In solchen Feldern können Datumswerte mit Uhrzeit gespeichert werden. Ob jedoch nur das Datum, nur die Uhrzeit oder beides gespeichert wird, hängt davon ab, was der Benutzer eingibt.

Die Eigenschaften Format und Eingabeformat

Um das zu beeinflussen, stellt Access für Datumsfelder zwei wichtige Eigenschaften zur Verfügung: Format und Eingabeformat.

Mit der Eigenschaft Format legen Sie fest, wie das Datum angezeigt wird. Wählen Sie dazu ein Format aus, das nur das Datum in der Form TT.MM.JJJJ anzeigt. Gibt der Benutzer dennoch eine zusätzliche Uhrzeit ein, wird die Uhrzeit zwar gespeichert, nicht aber angezeigt. Anders sieht es aus, wenn Sie für ein Feld ein Datumsformat festlegen, das Datum und Uhrzeit enthält. Gibt der Benutzer dann nur einen Teil, beispielsweise nur die Uhrzeit oder nur das Datum ein, wird auch nur dieser Teil angezeigt. Anders, als Sie vielleicht erwarten, wird der fehlende Teil nicht durch einen Standardwert wie das minimale Datum oder die Uhrzeit 00:00:00 aufgefüllt. Und genau hier treten dann auch Probleme in Abfragen und Vergleichen auf.

In manchen Fällen ist es daher sinnvoll, den Benutzer zur Eingabe des Datums in einem bestimmten Format zu zwingen. Dazu können Sie für ein Datumsfeld die Eigenschaft Eingabeformat festlegen. Legen Sie dort ein Format fest, das die Eingabe einer Uhrzeit erfordert, stellt Access sicher, dass der Benutzer auch eine Uhrzeit eingibt. Leider kennt Access jedoch kein Standardeingabeformat, das zur Eingabe eines Datums mit Uhrzeit zwingt. Wenn Sie ein solches Format nutzen möchten, müssen Sie also ein benutzerdefiniertes Format erstellen.

Benutzerdefiniertes Datums- und Zeitformat erstellen

Möchten Sie ein eigenes Format erstellen, klicken Sie in der Entwurfsansicht der Tabelle auf die Schaltfläche ... der Eigenschaft Eingabeformat. In dem nun angezeigten Dialog wählen Sie ein Format, das Ihrem Ziel recht nahe kommt, und klicken dann auf Bearbeiten. Sie können nun die Eigenschaften des Formats ändern. Für ein Datum trennen Sie die einzelnen Bestandteile durch einen Schrägstrich, für die Uhrzeit durch einem Doppelpunkt. Das Zeichen 9 steht für eine beliebige Ziffer, die 0 für führende Nullen. Klicken Sie auf Schließen und Fertigstellen, um die Änderungen am Eingabeformat zu speichern.

Mit dem in Bild 1 gezeigten Format wird das Datum also in der Form TT.MM.JJJJ HH:MM:SS abgefragt. Welche Zeichen dabei für die Trennung der Datumsbestandteile im Endeffekt verwendet werden, hängt von den länderspezifischen Einstellungen von Windows ab.

Bild 1: Definieren eines Eingabeformats.

Der Benutzer wird so zwar gezwungen, eine Zeit einzugeben, es ist ihm aber erlaubt, für alle Bestandteile 00 anzugeben. Das führt dann wiederum
dazu, dass Access das Datum nicht speichert. Möchten Sie also sicherstellen, dass der Anwender wirklich eine Zeit eingibt, sollten Sie für mindestens einen Teil das Symbol 9 verwenden. Möchten Sie den Anwender zur Eingabe der Stunde zwingen, verwenden Sie daher das Format 09/09/9999 09:00:00.

Prüfen auf Identität

Möchten Sie prüfen, ob es in einer Tabelle beziehungsweise einem Feld der Tabelle Datumsangaben gibt, die dem heutigen Datum entsprechen, müssen Sie prüfen, ob das Ergebnis mit dem aktuellen Datum identisch ist, das von der Funktion Datum geliefert wird.

Vergleichen Sie einen Feldwert mit dem Rückgabewert der Funktion Datum, wird der Feldwert nur mit einem Datum verglichen. Ist im Feldwert auch eine Zeitangabe gespeichert, wird diese nicht einfach ignoriert, sondern führt dazu, dass beide Werte als ungleich erkannt werden, auch wenn das Datum übereinstimmt. Der Ausdruck #01.01.2006 00:02# = Datum() hat somit auch dann den Wert false, wenn die Funktion Datum den 01.01.2006 liefert.

Es gibt mehrere Lösungen für das Problem. Die einfachste besteht darin, ein berechnetes Feld zu erzeugen, das nur den Datumsbestandteil des Feldes enthält. Dieses können Sie dann mit dem Rückgabewert der Funktion Datum vergleichen (Bild 2). Am einfachsten erreichen Sie das, indem Sie die Format-Funktion verwenden und als Format tt/mm/jjjj angeben.

Bild 2: Vergleichen eines Feldes mit dem aktuellen Datum.

SELECT tabDatumswerte.ID, tabDatumswerte.DatumundZeit, tabDatumswerte.Datum, tabDatumswerte.
Zeit, Date() AS Heute, tabDatumswerte.AktuellesDatum, Format([DatumundZeit],"
hh:nn:ss") AS ZeitAusDatum
FROM tabDatumswerte
WHERE (((Format([DatumundZeit],"hh:nn:ss"))=#17:00:00#));

Ähnliches gilt für den Vergleich von Zeiten. Werden diese als einzelne Werte gespeichert, gelingt ein Vergleich mit einem Zeitwert problemlos, falls Sie den Vergleichswert in der Form #00:00:00# angeben oder von einer Funktion zurückgeben assen, die einen Zeitwert liefert. Eine Abfrage, die korrekte Ergebnisse für den Vergleich von Zeiten mit der Uhrzeit 17:00:00 liefert, könnten beispielsweise wie folgt lauten:

Suchen nach Werten in der Vergangenheit und der Zukunft

Interessant ist in vielen Fällen auch die Prüfung, ob ein Datumswert in der Vergangenheit oder Zukunft liegt. Dazu müssen Sie die Datumswerte mit dem aktuellen Datum vergleichen und auf kleiner oder größer prüfen. Hierbei ergibt sich ein neues Problem. Verwenden Sie als Kriteriumsausdruck <Datum() erfüllen nur die Datensätze das Kriterium, deren Datumswert bei einer Sortierung nach Zeichenfolgen kleiner ist als das aktuelle Datum. Falls das aktuelle Datum der 01.01.2006 ist, würde zwar ein Datum 01.01.2005 als kleiner erkannt werden, nicht aber der 31.12.2005, obwohl das Datum definitiv in der Vergangenheit liegt. Das Datum wird jedoch als Zeichenfolge verglichen, und die Zeichenfolge "31.12.2005" ist nun mal größer als "01.01.2005", weil Letztere mit einer 0, die erste aber mit einerm 3 beginnt.

Um den Datumswert korrekt zu vergleichen, benötigen Sie also einen numerischen Wert, der dann nicht als Zeichenkette verglichen wird. Die Lösung ist die Funktion DatWert. Sie liefert einen numerischen Wert für ein Datum. Als Parameter übergeben Sie eine Zeichenkette, die ein gültiges Datum beinhaltet. Das können Sie mit der Format- Funktion aus einem Datumsfeld mit oder ohne Zeitangabe erzeugen. Mit folgendem Code definieren Sie in der Entwurfsansicht einer Abfrage ein berechnetes Feld Datumswert, das den numerischen Wert des Datums im Feld DatumundZeit enthält.

Datumswert
DatWert(Format([DatumundZeit];"tt.mm.jjjj"))

Dieses können Sie dann mit dem numerischen Wert des aktuellen Datums DatWert(Datum()) vergleichen (Bild 3).

Bild 3: Vergleichen eines Datumswertes mit dem Operator kleiner als.

Schon problematischer sind solche Vergleiche, wenn Sie auch die Uhrzeit berücksichtigen möchten. Falls Sie alle Datensätze ermitteln möchten, deren Datum unter Berücksichtigung der aktuellen und der gespeicherten Uhrzeit in der Vergangenheit liegt, bringt Sie die Funktion DatWert alleine nicht weiter. Sie liefert nämlich unabhängig von der gespeicherten Uhrzeit immer den gleichen Datumswert, wenn das Datum übereinstimmt. Für die Werte #01.01.2006 08:00:00# und #01.01.2006 19:00:00# liefert die Funktion also den gleichen Wert. Bei einem Vergleich wie dem in Bild 3 würden also alle Datensätze mit dem Datum des aktuellen Tages nicht mitgeliefert werden, weil der Tag nicht kleiner istals der aktuelle. Bei Angabe von <= als Vergleichsoperator würden hingegen auch die Datensätze geliefert, deren Uhrzeit in der Zukunft liegt.

Numerischen Datumswert und Zeitwert berechnen

Für solche Vergleiche benötigen Sie zwei berechnete Felder. In einem berechnen Sie mit der Funktion DatWert den numerischen Datumswert, mit dem anderen den Zeitwert des Datums. Diesen liefert die Funktion ZeitSeriell, der Sie die Stunde, die Minute und die Sekunde der Zeitangabe übergeben. Falls Sie diese aus einem Feld ermitteln möchten, können Sie dazu die Funktionen Stunde, Minute und Sekunde verwenden, denen Sie ein Datum mit Zeitangabe oder einen Zeitwert übergeben. Sie geben dann den jeweiligen Teil der Zeitangabe zurück.

Für beide Felder definieren Sie dann einen entsprechenden Vergleichsausdruck (Bild 4). Sie geben in der ersten Kriterienzeile für das Datum den Operator "<" an, in der zweiten Zeile "=". Für die zweite Zeile des Zeitfeldes geben Sie zusätzlich noch einen Vergleich mit der aktuellen Zeit und dem "<"-Operator an.

Bild 4: Formulieren der Suchkriterien.

Dieses Kriterium stellt sicher, dass alle Datensätze ausgewählt werden, bei denen ein kleineres Datum als das aktuelle gespeichert ist oder bei denen das Datum gleich dem aktuellen Datum ist, die Zeit aber vor der aktuellen Zeit liegt. Analog dazu definieren Sie natürlich Suchkriterien mit dem Operator ">=".

Suchen nach Datumswerten in einem bestimmten Zeitraum

Ähnlich sehen Suchkriterien aus, wenn Sie die Datensätze nach Monatsbestandteilen filtern möchten, beispielsweise wenn Sie Datensätze suchen, deren Datum in bestimmten Monaten des Vorjahres liegt. Dann müssen Sie zunächst je ein berechnetes Feld erzeugen, das den Monat des Datums berechnet, und eines, das das Jahr berechnet. Dazu übergeben Sie das Datum an die Funktionen Jahr und Monat. Für beide Felder definieren Sie dann Suchkriterien wie die in Bild 5.

Bild 5: Formulieren der Suchkriterien.

Im Beispiel werden Datensätze selektiert, deren Datum im ersten Quartal des Vorjahres liegt. <