sodele
Goto Top

Zeiten subtrahieren, um Dauer zu ermitteln

Wie kann man Dauer errechnen?

Hallo,

ich stehe gerade wieder auf dem Schlauch. Ich müsste zur Weiterverarbeitung durch zwei Zeitwerte deren Dauer ermitteln und weiß gerade nicht weiter. Mein bisheriger Ansatz:

set /p "1begin=Anfangszeit 1: "
set /p "1end=Endzeit 1: "
set /p "2begin=Anfangszeit 1: "
set /p "2end=Endzeit 1: "

set /a 1duration=%1end%-%1begin%
set /a 2duration=%2end%-%2begin%

ECHO Dauer 1: %1duration%
ECHO Dauer 2: %2duration%

funktioniert nicht, weil die Daten im Digitalformat [HH:MM:SS.sss] eingegeben werden und auch wieder so ausgegeben werden sollen, mit diesem Zeitformat aber ja nicht gerechnet werden kann. Wie kann ich das hinkriegen?

Content-ID: 180121

Url: https://administrator.de/forum/zeiten-subtrahieren-um-dauer-zu-ermitteln-180121.html

Ausgedruckt am: 19.12.2024 um 18:12 Uhr

bastla
bastla 06.02.2012 um 19:25:05 Uhr
Goto Top
Hallo Sodele!
Wie kann ich das hinkriegen?
Stringzerlegung anhand der Trennzeichen ":" und "." und mit den einzelnen Zahlenwerten (inkl Überträgen) weiter rechnen oder ein wenig VBS einbauen ...

Grüße
bastla
pieh-ejdsch
pieh-ejdsch 06.02.2012 um 19:33:24 Uhr
Goto Top
moin Sodele,
moin bastla,

bastla hat doch hier unten in Ähnliche Beiträge schon das passende Laufzeit bzw. Dauer einer Batch ermitteln!.
sonst Findest Du über die Suchfunktion bestimmt mehr passende Ergebnisse.

Gruß Phil
Sodele
Sodele 06.02.2012 um 19:56:39 Uhr
Goto Top
Vielen Dank euch beiden. Ich habe jetzt versucht, Biebers Code von: Mit Zeit rechnen ? umzuschreiben, um wenigstens den Rechenteil hinzubekommen, bevor ich mich an das Rückkonvertieren in das Digitalformat mache, aber die Batch wird einfach ohne Fehlermeldung geschlossen, und zwar egal ob die Millisekunden mit eingegeben werden oder nicht (da mir delims/tokens schon immer zu hoch war, wollte ich mal auf das zweite Trennzeichen "." verzichten, aber selbst damit gibt es kein Ergebnis):

set /p "1begin=Anfangszeit 1: "
set /p "1end=Endzeit 1: "
set /p "2begin=Anfangszeit 2: "
set /p "2end=Endzeit 2: "

for /f "delims=:, tokens=1-3" %%i in ("%1begin%") do Set /a Start1=%%i*3600+%%j*60+%%k
for /f "delims=:, tokens=1-3" %%i in ("%1end%") do Set /a Ende1=%%i*3600+%%j*60+%%k
for /f "delims=:, tokens=1-3" %%i in ("%2begin%") do Set /a Start1=%%i*3600+%%j*60+%%k
for /f "delims=:, tokens=1-3" %%i in ("%2end%") do Set /a Ende1=%%i*3600+%%j*60+%%k

set /a T1=Ende1-Start1
set /a T2=Ende2-Start2

Echo Dauer 1: %T1% sec Dauer 2: %T2% sec

Mit VBS kenne ich mich leider überhaupt nicht aus und wollte deshalb gern darauf verzichten. Müsste ich mir dafür extra was installieren?
bastla
bastla 06.02.2012 um 20:08:58 Uhr
Goto Top
Hallo Sodele!
Müsste ich mir dafür extra was installieren?
Nein - es darf nur VBS nicht deaktiviert sein.

Unter der Voraussetzung, dass alle Zeiten im angegebenen Format (also zumindest mit einem verpflichtenden Punkt als Trennzeichen und danach bis zu 3 Nachkommastellen) eingegeben werden, sollte das etwa so gehen:
@echo off & setlocal
set T=%temp%\TimeDiff.vbs
 >%T% echo Set a=WScript.Arguments:TS1=Left(Split(a(0),".")(1)^&"000",3):TS2=Left(Split(a(1),".")(1)^&"000",3):TSDiff=TS2-TS1:If TSDiff^<0 Then TSDiff=TSDiff+1000:SDiff=1/86400  
>>%T% echo T1=CDate(Split(a(0),".")(0)):T2=CDate(Split(a(1),".")(0)):Diff=FormatDateTime(T2-T1+1-SDiff,vbLongTime)^&"."^&Right("00"^&TSDiff,3):WScript.Echo Diff  

set /p "begin1=Anfangszeit 1: "  
set /p "end1=Endzeit 1: "  
set /p "begin2=Anfangszeit 2: "  
set /p "end2=Endzeit 2: "  

for /f "delims=" %%i in ('cscript //nologo %T% "%begin1%" "%end1%"') do set "duration1=%%i"  
for /f "delims=" %%i in ('cscript //nologo %T% "%begin2%" "%end2%"') do set "duration2=%%i"  

echo Dauer 1: %duration1%
echo Dauer 2: %duration2%
Die Zeilen 2 bis 4 erzeugen ein VBScript, das dann in weiterer Folge mit Parameterübergabe aufgerufen wird.

Grüße
bastla

[Edit: Komfortablere Angabe der Tausendstelsekunden ermöglicht [/Edit]
Sodele
Sodele 06.02.2012 um 20:23:50 Uhr
Goto Top
Cool. Vielen Dank, das hat super geklappt, nur leider verstehe ich davon nichts. Muss ich mir das VBS-Script wie eine eigene Batchssprache vorstellen? Gibt es zu VBS auch ein anfängerfreundliches Tutorial?
bastla
bastla 06.02.2012 um 20:34:56 Uhr
Goto Top
Hallo Sodele!

VBS bedeutet "Visual Basic Script" und ist daher ein "Basic-Dialekt", wobei zwar "Scriptsprache" besser passen würde, aber "Batchsprache" als Beschreibung auch ok ist ...

Hinsichtlich Tutorial könntest Du mal ins Microsoft Windows 2000 - Scripting-Handbuch (Teil 1) reinschauen ...
nur leider verstehe ich davon nichts.
Das oben verwendete Script in etwas weniger kompakter Form (und etwas ausführlicher kommentiert face-wink):
Set a = WScript.Arguments 'Array für Aufrufparameter (stehen danach als a(0), a(1), etc zur Verfügung) erzeugen  

TS1 = Left(Split(a(0), ".")(1) & "000", 3) 'ersten Parameter anhand des Punktes zerlegen; an den zweiten Teil - da der Index null-basiert ist, wird (1) verwendet - "000" anfügen und davon die ersten 3 Stellen von links als Tausendstelsekundenwert verwenden  
TS2 = Left(Split(a(1), ".")(1) & "000", 3) 'analog für den zweiten Parameter  
TSDiff = TS2 - TS1 'Tausendstelsekunden-Differenz berechnen  
If TSDiff < 0 Then TSDiff = TSDiff + 1000: SDiff = 1/86400 'bei negativem Ergebnis 1000 addieren und den Wert einer Sekunde (wird in Basic - und zB auch in Excel - als Bruchteil eines Tages angegeben) als Korrekturfaktor speichern  

T1 = CDate(Split(a(0), ".")(0)) 'ersten Parameter anhand des Punktes zerlegen und den ersten Teil in einen Zeitwert (für die Berechnung) konvertieren  
T2 = CDate(Split(a(1), ".")(0)) 'analog für den zweiten Parameter  
'Zeitdifferenz berechnen und dabei einfach einen Tag addieren (verhindert negative Ergebnisse) sowie den Korrekturfaktor aus der Tausendstelsekundenberechnung subtrahieren;  
'das Ergebnis wird als Zeitwert formatiert und daran ein Punkt sowie die Tausendstelsekunden-Differenz angefügt, wobei diese Differenz auf 3 Stellen (bei Bedarf mit führenden Nullen) gebracht wird  
Diff = FormatDateTime(T2 - T1 + 1 - SDiff, vbLongTime) & "." & Right("00" & TSDiff, 3)  
WScript.Echo Diff 'Ausgabe des Ergebnisses (kann vom aufrufenden Batch übernommen werden)  

Grüße
bastla
Biber
Biber 06.02.2012 um 20:58:49 Uhr
Goto Top
Moin Sodele,

nur der Vollständigkeit halber...

ich habe in meiner Jugend hier im Forum ein mehrzeiliges Tutorial "Umgang mit Datums- und Zeitvariablen im Batch" zusammengeharkt.
Um zu belegen, dass Rechnen mit Datumswerten im Batch eigentlich nicht geht.

Von daher empfehle ich (wie auch in dem Tutorial): Frag lieber jemand, der weiss, wie es geht --> also z.B. VBScript/JScript --> siehe weiter oben bei bastla.

Die beiden Probleme in deiner Schnipselvariante (oben, von 19;54h) sind allerdings
a) eine Batch-Sofort-Strafe für schlechten Programmierstil face-wink
b) eine Wie-im-richtigen-Leben-Sofort-Strafe für Programmieren mit Copy&Paste

Der schlechte Programmierstil, der sich innerhalb von Zehntelsekunden gerächt hat:

Benenne NIE NIE NIE in keiner Programmiersprache dieser Galaxie leichtfertig Variablennamen beginnend mit Ziffern, Unterstrichen, Sonderzeichen oder Umlauten.
Ist eine Sollbruchstelle - das holt dich immer ein.

In diesem Fall wurden die Variablennamen gar nicht als "%1end%" im Sinne von "inhalt der Variablen 1end" interpretiert.
Sondern als "%1end%" == Parameter 1 der Batchdatei (war leer) + der String "end%". Da kann bei der Zerlegung nix rauskommen.


Der Copy &Paste-Fehler --> Du setzt in deinen vier FOR/F-Anweisungen nicht Start1/Ende1 und Start2/Ende2 ... sondern 2x Start1/Ende1

Den ersten Fehler solltest du beheben durch Umbenamsen der Variablen in irgendetwas mit einem Buchstaben am Anfang.
Also statt "1begin" vielleicht "grzlbrnft" oder etwas anderes Wiedererkennbares.

Theoretischer Workaround, falls du aus religiösen oder aus Gründen der Gendergleichstellung auf Variablen beginnend mit Ziffern bestehst:
@echo off & setlocal enabledelayedexpansion
goto skip
set /p "1begin=Anfangszeit 1: "  
set /p "1end=Endzeit 1: "  
set /p "2begin=Anfangszeit 2: "  
set /p "2end=Endzeit 2: "  
:skip
set "1begin=15:19:13,04"  
set "1end=20:19:33,94"  
set "2begin=17:33:44,77"  
set "2end=23:00:23,11"  

for /f "delims=:, tokens=1-3" %%i in ("!1begin!") do Set /a Start1=%%i*3600+%%j*60+%%k  
for /f "delims=:, tokens=1-3" %%i in ("!1end!") do Set /a Ende1=%%i*3600+%%j*60+%%k  
for /f "delims=:, tokens=1-3" %%i in ("!2begin!") do Set /a Start2=%%i*3600+%%j*60+%%k  
for /f "delims=:, tokens=1-3" %%i in ("!2end!") do Set /a Ende2=%%i*3600+%%j*60+%%k  

set /a T1=Ende1-Start1
set /a T2=Ende2-Start2

Echo Dauer 1: %T1% sec Dauer 2: %T2% sec

Ausgabe-->
d:\temp>e:\schnipsel\DauerBerechnen.cmd
Dauer 1: 18020 sec Dauer 2: 19599 sec

Grüße
Biber
Sodele
Sodele 06.02.2012 um 21:43:49 Uhr
Goto Top
Vielen Dank für die Hinweise. Nein, dass die Zahlen am Anfang stehen hat keinen religiösen Sinn, sondern fand ich einfach übersichtlicher (denn es werden am Ende mehr als nur zwei Berechnungen gebraucht. Ich denke, dass 5-6 am Stück pro Batch so normal werden sollten). Ich gelobe Besserung.