Mit Zeiten rechnen

Zeit- und Datumsangaben sind elementarer Bestandteil vieler Anwendungen. Da sollte man wissen, wie man mit diesen Daten rechnet. Dabei ist es einerlei, ob es um das Ermitteln einer Zeitspanne zwischen zwei Zeitangaben oder um das Summieren von Zeiten geht – Stolperfallen gibt es dabei eine ganze Reihe. Dieser Beitrag zeigt, wie Sie die Klippen beim Rechnen mit Zeiten umgehen, egal ob in VBA, Abfragen, Formularen oder Berichten.

Wie Access Zeiten speichert

Grundlegende Voraussetzung für die Arbeit mit Datums- und Zeitwerten ist die Kenntnis der Art der internen Speicherung dieser Daten unter Access. Es speichert Zeiten im Double-Format, wobei die Stellen vor dem Komma die Anzahl der Tage seit dem 30.12.1899 angeben (1 bedeutet 31.12.1899, 39539 steht für den 1.4.2008) und die Stellen hinter dem Komma die Uhrzeit, wobei 0 genau Mitternacht entspricht und 0,5 zwölf Uhr mittags.

Entgegen den üblichen Vorstellungen kann Access auch mit Zeiten vor dem 30.12.1899 arbeiten. Dazu verwenden Sie einfach ganze Zahlen mit negativem Vorzeichen. Experimente zeigten, dass beim 1.1.100 aber definitiv Schluss ist und der Geburtstag von Jesus Christus zumindest nicht als Jahreszahl in Ihre Datenbank Einzug halten wird. Grundlegende Informationen zu diesem Thema erhalten Sie im Beitrag Datum und Zeit mit Access (Shortlink 216). Dort erläutern wir auch die von VBA bereitgestellten Funktionen etwa zur formatierten Ausgabe von Zeitangaben oder zum Rechnen mit den Funktionen DateAdd oder DateDiff.

Zeitspannen berechnen

Die DateDiff-Funktion berechnet die Zeitspanne zwischen zwei Daten, wobei die Zeitspanne in einer beliebigen Zeiteinheit wie beispielsweise Sekunden, Stunden oder auch Tagen angegeben werden kann. Ein separates Pendant für die Berechnung von Differenzen zwischen zwei Uhrzeiten findet sich unter VBA nicht. Unter VBA berechnen Sie Zeitspannen etwa ganz einfach als Differenz zweier Literale. Im Direktfenster würde eine Beispieleingabe folgendes Ergebnis liefern:

 #10:00:00# - #8:00:00#
8,33333333333334E-02

Das Ergebnis ist eine in wissenschaftlicher Schreibweise dargestellte Zahl, die in ein Datum umgewandelt so aussieht:

 CDate(8.33333333284827E-02 )
02:00:00

Beachten Sie, dass Access die Differenz im Direktfenster mit einem Komma als Dezimaltrennzeichen ausgibt, bei Berechnungen jedoch einen Punkt als solches erwartet.

Schwieriger wird es bei Zeitspannen, deren Anfangs- und Endzeit nicht das gleiche Datum haben. Die Berechnung einer typischen Nachtschicht von 22 Uhr bis 6 Uhr am folgenden Tag führt so zu einer negativen Zahl:

 #6:00:00# - #22:00:00#
-0,666666666666667

Das ist auch logisch, wenn man sich ansieht, wie die Double-Zahlen aussehen, mit denen Access intern rechnet:

 CDbl(#6:00:00#)
0,25
 CDbl(#22:00:00#)
0,916666666666667

Was also tun, wenn Sie Zeitspannen zweier Zeiten ermitteln möchten, die nicht an einem Tag liegen Das Problem lässt sich leicht lösen, wenn es um Zeiten geht, die auf den gleichen Tag fallen oder maximal einen Tag auseinanderliegen – also beispielsweise Arbeitszeiten. Obiges Beispiel würde man mit folgender IIf-Bedingung abrunden:

 IIf(#6:00:00# - #22:00:00# > 0, #6:00:00# - #22:00:00#, #6:00:00# - #22:00:00# + 1)
0,333333333333333

Diese prüft, ob die Differenz negativ ist, und addiert in dem Fall den Wert 1 hinzu. Dies entspricht genau einem Tag – Sie erinnern sich, die Stellen vor dem Komma sind mit der Anzahl der Tage seit dem 30.12.1899 gleichzusetzen. Einfacher und zuverlässiger, auch für größere Zeitspannen, funktioniert dies, wenn Sie das Datum mit angeben:

 #1/3/2008 6:00:00# - #1/2/2008 22:00:00#
0,333333333335759

Aber halt: Das Ergebnis stimmt in den hinteren Nachkommastellen nicht mit dem tatsächlichen Ergebnis überein – was ist dort schiefgelaufen

Der Grund liegt ganz einfach in Ungenauigkeiten beim Rechnen mit Gleitkommazahlen. Für genaue Ergebnisse gibt es zwei Möglichkeiten: Entweder man rechnet getrennt nach Datum und Zeit oder man verwendet doch die DateDiff-Funktion.

Die getrennte Rechnung sieht so aus:

 #1/3/2008# - #1/2/2008# + #6:00:00# - #22:00:00#
0,333333333333333

Mit DateDiff geht es folgendermaßen:

Function ZeitdifferenzHMS(dat1 As Date, dat2 As Date) As String
    Dim s As Long
    Dim h As Long
    Dim n As Long
    s = DateDiff("s", dat1, dat2)
    h = Int(s / 3600)
    n = Int((s Mod 3600) / 60)
    s = Int(n Mod 60)
    ZeitdifferenzHMS = Format(h, "00") & ":" & Format(n, "00") & ":" & Format(s, "00")
End Function

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

Workplace

Jahresabonnement TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar