Frage deutsch
~~~~~~~~~~~~
Wie ermittle ich die Zeitspanne zwischen 2 Zeitpunkten?
Wie berechne ich eine Zeitdifferenz über mehrere Tage?
Wie berechne ich eine Zeitdifferenz, die sich über mehrere Tage erstreckt
?
Wie kann ich die Zeitdifferenz zwischen zwei Zeitpunkten in Sekunden, Stunden
und Tagen ermitteln. Die Zeitpunkte Z1 und Z2 liegen jeweils im DATE$ und TIME$
Format vor. T2 kann vor oder nach T1 liegen. Schaltjahre sollen berücksichtigt
werden. Ich will damit die Rest-Wehrdienstzeit oder die Anzahl der Tage bis zu
meinem 18. Geburtstag anzeigen.
Question English
~~~~~~~~~~~~~~~
How to calculate the time difference between two date/time values?
Antwort 1
~~~~~~~~~~~~~~~
[ von stef im QB-Forum, 18.4.2005 - 8.12.2005 ]
Für den Programmierwettbewerb auf qb-city.de habe ich seinerzeit die Funktion
ZEITDIFF geschrieben, die genau das gewünschte leistet. Weitere Information
findest Du im Kommentar des Programms.
'*******************************************************************************
' ZEITDIFF.BAS = Ermittelt die Zeitdifferenz zwischen 2 Zeitpunkten in
Sekunden
' ============
' Dieses QBasic-Programm ermittelt die Zeitdifferenz zwischen zwei
Zeitpunkten.
' Die Zeitpunkte werden jeweils durch ihr Datum im Format "MM-TT-JJJJ" und
ihre
' Uhrzeit im Format "hh:mm:ss" angegeben. Datum und Uhrzeit werden also
in
' demselben Format wie bei den QBasic-Funktionen DATE$ und TIME$
vorausgesetzt.
' Daher kann man die Zeitdifferenz zwischen einem in der Vergangenheit
liegenden
' Zeitpunkt und dem aktuellen Zeitpunkt durch folgenden Funktionsaufruf
' anzeigen: PRINT ZeitDiff (Datum$, Uhrzeit$, DATE$, TIME$).
'
' Die Zeitdifferenz wird in Sekunden ermittelt. Die Funktion berrechnet
die
' Zeitdifferenz immer korrekt, selbst wenn dazwischen Schaltjahre oder
' Jahrhunderte liegen.
'
' (c) stef, 18.4.2005
'*******************************************************************************
'
DECLARE FUNCTION ZeitDiff# (Datum1 AS STRING, Zeit1 AS STRING, Datum2 AS
STRING, Zeit2 AS STRING)
CLS
PRINT "Gib den ersten (frueheren) Zeitpunkt ein"
INPUT ".... Datum MM-TT-JJJJ : ", Datum1$
INPUT ".... Uhrzeit hh:mm:ss : ", Zeit1$
PRINT
PRINT "Gib den zweiten (spaeteren) Zeitpunkt ein"
INPUT ".... Datum MM-TT-JJJJ : ", Datum2$
INPUT ".....Uhrzeit hh:mm:ss : ", Zeit2$
PRINT
PRINT "Die Zeitdifferenz betraegt ";
PRINT ZeitDiff#(Datum1$, Zeit1$, Datum2$, Zeit2$); " Sekunden"
'
FUNCTION ZeitDiff# (Datum1 AS STRING, Zeit1 AS STRING, Datum2 AS STRING,
Zeit2 AS STRING)
'Errechnet die Zeitdifferenz zwischen zwei Zeitpunkten in Sekunden
'Parameter: Datum1 -> MM-TT-JJJJ
' Zeit1 -> hh:mm:ss
' Datum2 -> MM-TT-JJJJ
' Zeit2 -> hh:mm:ss
DIM Sek1 AS LONG 'Sekunden seit Tagesbeginn
DIM Sek2 AS LONG
'
DIM Tag1 AS INTEGER 'ganze Tage seit Monatsbeginn
DIM Tag2 AS INTEGER
'
DIM Monat(1 TO 12) AS INTEGER 'Tage bis zum Monatsbeginn im Jahr
DIM Monat1 AS INTEGER 'Monatsnummer
DIM Monat2 AS INTEGER
'
DIM Jahr1 AS INTEGER 'Jahreszahl
DIM Jahr2 AS INTEGER
'
DIM Schalttag1 AS INTEGER 'Anzahl Schalttage seit dem Jahre 1
DIM Schalttag2 AS INTEGER
'
'----- Z„hlen der Sekunden seit Tagesbeginn -----
Sek1 = VAL(MID$(Zeit1, 7)) 'Sekunden
Sek2 = VAL(MID$(Zeit2, 7))
'
Sek1 = Sek1 + VAL(MID$(Zeit1, 4, 2)) * 60 'Minuten
Sek2 = Sek2 + VAL(MID$(Zeit2, 4, 2)) * 60
'
Sek1 = Sek1 + VAL(LEFT$(Zeit1, 2)) * 3600 'Stunden
Sek2 = Sek2 + VAL(LEFT$(Zeit2, 2)) * 3600
'
'----- Speichern der Tage vor einem Monat -----
Monat(1) = 0: Monat(7) = 181
Monat(2) = 31: Monat(8) = 212
Monat(3) = 59: Monat(9) = 243
Monat(4) = 90: Monat(10) = 273
Monat(5) = 120: Monat(11) = 304
Monat(6) = 151: Monat(12) = 334
'
'----- Berechnen der ganzen Tage seit Jahresbeginn -----
Tag1 = VAL(MID$(Datum1, 4, 2)) - 1
Monat1 = VAL(LEFT$(Datum1, 2))
Tag1 = Tag1 + Monat(Monat1)
'
Tag2 = VAL(MID$(Datum2, 4, 2)) - 1
Monat2 = VAL(LEFT$(Datum2, 2))
Tag2 = Tag2 + Monat(Monat2)
'
'----- Jahreszahl ermitteln -----
Jahr1 = VAL(MID$(Datum1, 7))
Jahr2 = VAL(MID$(Datum2, 7))
'
'----- Ermitteln ob im aktuelle Jahr ein Schalttag war ---
IF Monat1 > 2 THEN
IF (Jahr1 MOD 4 = 0 AND Jahr1 MOD 100 <> 0) OR Jahr1 MOD 400 = 0
THEN
Schalttag1 = 1
END IF
END IF
IF Monat2 > 2 THEN
IF (Jahr2 MOD 4 = 0 AND Jahr2 MOD 100 <> 0) OR Jahr2 MOD 400 = 0
THEN
Schalttag2 = 1
END IF
END IF
'
'----- Erechnen der Schalttage seit dem Jahre 1 -----
Jahr1 = Jahr1 - 1
Jahr2 = Jahr2 - 1
Schalttag1 = Schalttag1 + Jahr1 \ 4 - Jahr1 \ 100 + Jahr1 \ 400
Schalttag2 = Schalttag2 + Jahr2 \ 4 - Jahr2 \ 100 + Jahr2 \ 400
'
'----- Berechnen der Zeitdifferenz -----
ZeitDiff = Sek2 - Sek1 + (Tag2 - Tag1 + Schalttag2 - Schalttag1) * 86400 +
(Jahr2 - Jahr1) * 31536000#
END FUNCTION
Das obige Programm steht im Verzeichnis Progs\ zur Verfügung sowie online
unter www.antonis.de/faq/progs/zeitdiff.bas .
Thomas Antoni hat dieses Programm noch etwas abgewandelt, so dass es die
Zeitdifferenz nicht nur in Sekunden, sondern auch in Tagen, Stunden, Minuten und
Sekunden anzeigt. Somit ist es bestens geeignet für Wehrdienstleistende,
Knastbrüder und Vorruheständler geeignet, die sich damit die Resttage bis zur
totalen Freiheit ausrechnen können.
Und so sieht das abgewandelte Programm TAGDIFF.BAS aus:
'****************************************************************************
' TAGDIFF.BAS = Ermittelt die Zeitdifferenz zwischen 2 Zeitpunkten in
Tagen
' ============
' Dieses QBasic-Programm ermittelt die Zeitdifferenz zwischen zwei
' Zeitpunkten. Die Zeitpunkte werden jeweils durch ihr Datum im Format
' "MM.TT.JJJJ" und ihre Uhrzeit im Format "hh:mm:ss" eingegeben.
' Die FUNCTION ZeitDiff# ermittelt die Zeitdifferenz in Sekunden zwischen
' dem frueheren Zeitpunkt 1 und dem spaeteren Zeitpunkt 2.
' Die Zeitdifferenz wird in Sekunden sowie in
Tagen/Stunden/Minuten/Sekunden
' angezeigt.
' Die Funktion ZeitDiff# berechnet die Zeitdifferenz immer korrekt,
selbst
' wenn dazwischen Schaltjahre oder Jahrhunderte liegen.
'
' Achtung: Es gibt keine Plausibilitaetskontrollen fuer die Eingaben.
Daher
' beendet sich das Programm bei Fehleingaben!
'
' (c) stef, mit Erweiterungen von Thomas Antoni, 18.4.2005 - 8.12.2005
'****************************************************************************
'
DECLARE FUNCTION ZeitDiff# (Datum1 AS STRING, Zeit1 AS STRING, Datum2 AS
STRING, Zeit2 AS STRING)
DO: WIDTH 80, 25
CLS
PRINT " Zeitdifferenz-Rechner"
PRINT "------------------------------------------------"
PRINT ">>> Bitte alle Eingaben formatgetreu machen.
<<<"
PRINT ">>> Gegebenenfalls eine Null voranstellen! <<<"
PRINT
PRINT "Gib den ersten (frueheren) Zeitpunkt ein"
INPUT ".... Datum MM.TT.JJJJ : ", Datum1$
INPUT ".... Uhrzeit hh:mm:ss : ", Zeit1$
PRINT
PRINT "Gib den zweiten (spaeteren) Zeitpunkt ein"
INPUT ".... Datum MM.TT.JJJJ : ", Datum2$
INPUT ".... Uhrzeit hh:mm:ss : ", Zeit2$
PRINT
SecDiff# = ZeitDiff#(Datum1$, Zeit1$, Datum2$, Zeit2$)
'
Tage# = INT(SecDiff# / 86400) '1 Tag hat 86400 Sekunden)
Stunden# = INT((SecDiff# - Tage# * 86400) / 3600)
Minuten# = INT((SecDiff# - Tage# * 86400 - Stunden# * 3600) / 60)
Sekunden# = SecDiff# - Tage# * 86400 - Stunden# * 3600 - Minuten# * 60
'
PRINT "Die Zeitdifferenz betraegt ";
PRINT SecDiff#; " Sekunden"
PRINT
PRINT "Das sind ..."
PRINT Tage#, "Tage"
PRINT Stunden#, "Stunden"
PRINT Minuten#, "Minuten"
PRINT Sekunden#, "Sekunden"
PRINT
PRINT "Neue Berechnung....[Beliebige Taste] Beenden....[Esc]"
DO: taste$ = INKEY$: LOOP WHILE taste$ = ""
IF taste$ = CHR$(27) THEN END
LOOP
'
FUNCTION ZeitDiff# (Datum1 AS STRING, Zeit1 AS STRING, Datum2 AS STRING,
Zeit2 AS STRING)
'Errechnet die Zeitdifferenz zwischen zwei Zeitpunkten in Sekunden
'Parameter: Datum1 -> TT.MM.JJJJ
' Zeit1 -> hh:mm:ss
' Datum2 -> TT.MM.JJJJ
' Zeit2 -> hh:mm:ss
DIM Sek1 AS LONG 'Sekunden seit Tagesbeginn
DIM Sek2 AS LONG
'
DIM Tag1 AS INTEGER 'ganze Tage seit Monatsbeginn
DIM Tag2 AS INTEGER
'
DIM Monat(1 TO 12) AS INTEGER 'Tage bis zum Monatsbeginn im Jahr
DIM Monat1 AS INTEGER 'Monatsnummer
DIM Monat2 AS INTEGER
'
DIM Jahr1 AS INTEGER 'Jahreszahl
DIM Jahr2 AS INTEGER
'
DIM Schalttag1 AS INTEGER 'Anzahl Schalttage seit dem Jahre 1
DIM Schalttag2 AS INTEGER
'
'----- Zaehlen der Sekunden seit Tagesbeginn ------
Sek1 = VAL(MID$(Zeit1, 7)) 'Sekunden
Sek2 = VAL(MID$(Zeit2, 7))
'
Sek1 = Sek1 + VAL(MID$(Zeit1, 4, 2)) * 60 'Minuten
Sek2 = Sek2 + VAL(MID$(Zeit2, 4, 2)) * 60
Sek1 = Sek1 + VAL(LEFT$(Zeit1, 2)) * 3600 'Stunden
Sek2 = Sek2 + VAL(LEFT$(Zeit2, 2)) * 3600
'
'----- Speichern der Tage vor einem Monat ---------
Monat(1) = 0: Monat(7) = 181
Monat(2) = 31: Monat(8) = 212
Monat(3) = 59: Monat(9) = 243
Monat(4) = 90: Monat(10) = 273
Monat(5) = 120: Monat(11) = 304
Monat(6) = 151: Monat(12) = 334
'
'----- Berechnen der ganzen Tage seit Jahresbeginn -----
Tag1 = VAL(LEFT$(Datum1, 2)) - 1
Monat1 = VAL(MID$(Datum1, 4, 2))
Tag1 = Tag1 + Monat(Monat1)
'
Tag2 = VAL(LEFT$(Datum2, 2)) - 1
Monat2 = VAL(MID$(Datum2, 4, 2))
Tag2 = Tag2 + Monat(Monat2)
'
'----- Jahreszahl ermitteln -----
Jahr1 = VAL(MID$(Datum1, 7))
Jahr2 = VAL(MID$(Datum2, 7))
'
'----- Ermitteln ob im aktuelle Jahr ein Schalttag war ---
IF Monat1 > 2 THEN
IF (Jahr1 MOD 4 = 0 AND Jahr1 MOD 100 <> 0) OR Jahr1 MOD 400 = 0
THEN
Schalttag1 = 1
END IF
END IF
IF Monat2 > 2 THEN
IF (Jahr2 MOD 4 = 0 AND Jahr2 MOD 100 <> 0) OR Jahr2 MOD 400 = 0
THEN
Schalttag2 = 1
END IF
END IF
'
'----- Erechnen der Schalttage seit dem Jahre 1 -----
Jahr1 = Jahr1 - 1
Jahr2 = Jahr2 - 1
Schalttag1 = Schalttag1 + Jahr1 \ 4 - Jahr1 \ 100 + Jahr1 \ 400
Schalttag2 = Schalttag2 + Jahr2 \ 4 - Jahr2 \ 100 + Jahr2 \ 400
'
'----- Berechnen der Zeitdifferenz -----
ZeitDiff = Sek2 - Sek1 + (Tag2 - Tag1 + Schalttag2 - Schalttag1) * 86400 +
(Jahr2 - Jahr1) * 31536000#
END FUNCTION
Das obige Programm steht im Verzeichnis Progs\ zur Verfügung sowie online
unter www.antonis.de/faq/progs/tagdiff.bas .
Antwort 2
~~~~~~~~~~~~~~~~
[ von Andreas Meile ( http://dreael.catty.ch ) im QB-Forum,
18.4.2005 ]
Gehe auf meine Seite
http://dreael.catty.ch/Deutsch/Download/DatumBerechnung.html
und downloade die dortigen Datumsarithmetik-Routinen. Nun würde ich das Ganze
wie folgt einbinden:
TYPE Zeitstempel
anzTage AS LONG
anzSekunden AS SINGLE
END TYPE
'
SUB Jetzt(z AS Zeitstempel)
z.anzSekunden = TIMER
d$ = DATE$
z.anzTage = AnzTageSeit&(VAL(MID$(d$, 4, 2)), VAL(LEFT$(d$, 2)),
VAL(RIGHT$(d$, 4)))
END SUB
'
FUNCTION DifferenzAnzSekunden#(z1 AS Zeitstempel, z2 AS Zeitstempel)
DifferenzAnzSekunden# = 86400# * CDBL(z2.anzTage - z1.anzTage) +
CDBL(z2.anzSekunden - z1.anzSekunden)
END FUNCTION
'
' Hauptprogramm
DIM zsStart AS Zeitstempel, zsSpaeter AS Zeitstempel
' Zu Beginn
Jetzt zsStart
'
' Hier längere Verarbeitung
'
' Irgendwann später
Jetzt zsSpaeter
PRINT "Programm läuft seit"; DifferenzAnzSekunden#(zsStart, zsSpaeter);
"Sekunden"
Hinweis: Nur Entwurf, d.h. nicht auf Fehlerfreiheit getestet.
*** Anmerkung
QB kennt im Gegensatz zu allen heutigen Betriebssystemen und
Programmiersprachen keinen Timestamp-Datentyp, wie ich ihn oben definiert habe.
Vor allem ist es nicht möglich, Datum und Uhrzeit als sog. atomare Operation
auslesen. QB kann hier übrigens nichts dafür, denn dies rührt bereits von MS-DOS
her, wo man für das Auslesen der Zeit auch zwei separate CALL INTERRUPTs (INT
21h/AH=2Ah für Datum, INT 21h/AH=2Ch) benötigt.
Warum dies ein Problem werden kann: Nehmen wir einmal an, dass die Ausführung
der Operation
z.anzSekunden = TIMER
um 23.59:59.9999 Uhr erfolgt und die Operation
d$ = DATE$
bereits am nächsten Tag um 0.00:00.0001 Uhr. Jeder kann sich nun vorstellen,
was passiert: Wir liegen volle 24 h daneben.
Glücklicherweise aber können wir dies mit folgender Methode umrunden:
d1$ = DATE$
z.anzSekunden = TIMER
d2$ = DATE$
IF d1$ = d2$ THEN
d$ = d1$ ' Wir liegen auf einer völlig unkritischen Zeit
ELSE
' Zeiten sind verschieden, d.h. wir haben genau den Mitternachts-Rollover
erwischt
IF z.anzSekunden < 43200! THEN
d$ = d2$ ' Die TIMER-Abfrage erfolgte bereits am neuen Tag
ELSE
d$ = d1$ ' Die TIMER-Abfrage erfolgte noch am alten Tag
END IF
END IF
Erst mit dieser Änderung arbeitet die Zeitabfrageroutine vollkommen
"bullet-proof". :-)
Antwort 3
~~~~~~~~
[ Von NicTheQuick im QB-Forum, 2001 ]
Wie kann ich die Zeitdifferenz zwischen zwei Uhrzeiten ermitteln? Z.B.
zwischen 10:32:55 h und 01:12:04 h ?
Ich hab es damals so gemacht, dass ich die Uhrzeit in Sekunden
umgerechnet hab:
10:32:55 -> Sekunden1
01:12:04 -> Sekunden2
Sekunden1=(3600*10)+(60*32)+55=37975
Sekunden2=(3600*1)+ (60*12)+4 = 4324
'
Differenz=Sekunden1-Sekunden2 =33651
'
Stunden=fix(Differenz/3600)=9
Differenz=Differenz mod 3600=1251
'
Minuten=fix(Differenz/60)=20
Sekunden=Differenz mod 60=51
'
Klaro? Vielleicht gibt es auch andere Möglichkeiten, aber diese hier habe ich
selbst 'rausgefunden.
[ The QBasic-MonsterFAQ --- Start Page: www.antonis.de/faq ]