Zeitmessung mit Batch

Zeit messen ist mit Batch kein Problem und oftmals eine nette Spielerei.

Code:

set /a timerstart=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)
REM packing zip archive
%wd%\7za.exe a -bd -ssw "%job-ziel%.zip" "%job-quelle%" > nul
set /a timerstop=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)
set /a timeseks=(%timerstop%-%timerstart%)
set /a timemins=(%timerstop%-%timerstart%)/60
echo Sekunden: %timeseks% -- Minuten: %timemins%

Erläuterung:
Also, timerstart nimmt die aktuelle Uhrzeit und rechnet aus, wieviele Sekunden seit 00:00 Uhr verstrichen sind.
Der 2. Timer, timerstop, rechner ebenfalls die Sekunden seit 00 Uhr aus. Zieht man diese jetzt von der Startzeit ab so bleibt die Anzahl in Sekunden übrig, die zwischen den Timern verstrichen ist.
Das bedeutet natürlich auch, dass eine Zeitberechnung von einem Tag in den nächsten nicht funktioniert. Start und Stop müssen zwischen 00 Uhr und 23:59 Uhr des selben Tages liegen.

Details zu dieser Art der Zeitmessung:
Diese Berechnung ist bereits eine optimierte Variante. Grundsätzlich würde in 80% der Fälle auch

set /a timerstart=((%time:~0,2%)*60*60)+((%time:~3,2%)*60)+(%time:~6,2%)

funktionieren; diese Variante findet man auch überall im Netz.
Ich beobachtete jedoch Probleme bei Zeitberechnungen, wenn mit den Zahlen „08“ und „09“ hantiert wurde.
Also beispielsweise um 16:08:09 Uhr wird ein Timer aktiviert. Dann rechnet dieser eigentlich
((16)*60*60)+((08)*60)+(09)
Batch kommt damit aber nicht klar, da er dezimale Zahlen und oktale Zahlen durcheinander bringt. Um trotzdem mit Uhrzeiten mit „08“ und „09“ rechnung zu können habe ich die Zeile ergänzt:

set /a timerstart=((1%time:~0,2%-100)*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)

Nun wird also bei 16:08:09 gerechnet:
((116-100)*60*60)+((108-100)*60)+(109-100)
Funktioniert 🙂

Update:
Eine etwas komplexere Lösung mit der Berücksichtigung des Datums wurde von einem Leser via Kommentar eingereicht:

@echo off

REM dynamisch mit %TIME% oder Zahlenformat des endtime Beispiels nehmen
set starttime=%TIME%
set endtime=00:15:26,92
set startdate=08.09.2012
set enddate=09.09.2012

REM einstellige Uhrzeiten korrigieren
set starttime=%starttime: =%
set endtimehh=%endtime:~1,1%
if ‘%endtimehh%’ == ‘:’ set endtime=0%endtime%
echo endtime: %endtime%

set starttimehh=%starttime:~1,1%
if ‘%starttimehh%’ == ‘:’ set starttime=0%starttime%
echo starttime: %starttime%

set /a timerstart=((1%starttime:~0,2%-100)*60*60)+((1%starttime:~3,2%-100)*60)+(1%starttime:~6,2%-100)
echo timerstart: %timerstart%

set /a daymodifier=86400*((1%enddate:~0,2%)-(1%startdate:~0,2%))
rem set daymodifier=86400
echo daymodifier: %daymodifier%

set /a timerstop=(((1%endtime:~0,2%-100)*60*60)+((1%endtime:~3,2%-100)*60)+(1%endtime:~6,2%-100))+%daymodifier%
echo timerstop: %timerstop%

rem =======================

set /a timeseks=(%timerstop%-%timerstart%)
echo Sekunden: %timeseks%

set /a timemins=((%timerstop%-%timerstart%)/60)
echo Minuten: %timemins%

set /a timeminsseks=((((%timerstop%-%timerstart%)/60)*60)-(%timerstop%-%timerstart%))*-1
echo Zeit: %timemins%:%timeminsseks%

pause

15 Kommentare

  1. Hallo!

    Bei mir funktioniert die Variante

    set /a timerstart=((%time:~0,2%-100)*60*60)+((%time:~3,2%-100)*60)+(%time:~6,2%-100)
    

    denn bei %time:~0,2% wird immer eine Zahl ohne führende Null ausgegeben. Also wenn wer Probleme hat, einfach den Befehl mit „echo“ davor mal eingeben und schauen, wie bei ihm die Zahlen zurückgegeben werden.

  2. Also wenn ich deinen Code

    set /a timerstart=((%time:~0,2%-100)*60*60)+((%time:~3,2%-100)*60)+(%time:~6,2%-100)

    ausführe dann erhalte ich

    -329227

    .

    Ich denke mal du hast vergessen die

    -100

    überall zu entfernen.

    Und selbst wenn du die

    -100

    überall entfernst und der Code dann

    set /a a=((%time:~0,2%)*60*60)+((%time:~3,2%)*60)+(%time:~6,2%)

    lauetet wirst du Probleme bekommen sobald einer der Zeitvariablen „08“ oder „09“ annimmt, so wie oben beschrieben.

    Also die Zeit 16:08:09 Uhr würde bei dieser Codezeile (ohne die 100er Ergänzungen) folgendes generieren:

    c:>test.bat
    Ungültige Zahl. Numerische Konstanten sind entweder dezimale (17),
    hexadezimale (0x11) oder oktale (021) Zahlen.
    ECHO ist ausgeschaltet (OFF).

    (Screenshot)

    Warum das so ist habe ich ja oben beschrieben. Und die Lösung dafür ist halt die Ergänzung mit den 100er Rechenschritten.

  3. Um einen Datumswechsel mitzubeachten kann der Code um folgendes erweitert werden:

    @echo off
    
    set starttime=23:13:45,76
    set endtime=00:15:26,92
    set startdate=27.09.2012
    set enddate=28.09.2012
    
    set /a timerstart=((1%starttime:~0,2%-100)*60*60)+((1%starttime:~3,2%-100)*60)+(1%starttime:~6,2%-100)
    echo timerstart: %timerstart%
    
    set /a daymodifier=86400*((%enddate:~0,2%)-(%startdate:~0,2%))
    rem set daymodifier=86400
    echo daymodifier: %daymodifier%
    
    set /a timerstop=(((1%endtime:~0,2%-100)*60*60)+((1%endtime:~3,2%-100)*60)+(1%endtime:~6,2%-100))+%daymodifier%
    echo timerstop: %timerstop%
    
    rem =======================
    
    set /a timeseks=(%timerstop%-%timerstart%)
    echo Sekunden: %timeseks% 
    
    set /a timemins=((%timerstop%-%timerstart%)/60)
    echo Minuten: %timemins%
    
    set /a timeminsseks=((((%timerstop%-%timerstart%)/60)*60)-(%timerstop%-%timerstart%))*-1
    echo Zeit: %timemins%:%timeminsseks%
  4. Ergänzung zur Vermeidung von Rechenfehlern bei Uhrzeiten die nur Einziffrig sind (vor 10 Uhr morgens) bitte folgenden Code nach dem init der datum & zeitvariablen einfügen:

    set endtimehh=%endtime:~1,1%
    if ‚%endtimehh%‘ == ‚:‘ set endtime=0%endtime%
    echo endtime: %endtime%

    set starttimehh=%starttime:~1,1%
    if ‚%starttimehh%‘ == ‚:‘ set starttime=0%starttime%
    echo starttime: %starttime%

    Gruß

  5. Also zusammengefasst wäre das dann:

    @echo off
    
    set starttime=23:13:45,76
    set endtime=00:15:26,92
    set startdate=27.09.2012
    set enddate=28.09.2012
    
    REM einstellige Uhrzeiten korrigieren
    set endtimehh=%endtime:~1,1%
    if ‘%endtimehh%’ == ‘:’ set endtime=0%endtime%
    echo endtime: %endtime%
    
    set starttimehh=%starttime:~1,1%
    if ‘%starttimehh%’ == ‘:’ set starttime=0%starttime%
    echo starttime: %starttime%
    
    set /a timerstart=((1%starttime:~0,2%-100)*60*60)+((1%starttime:~3,2%-100)*60)+(1%starttime:~6,2%-100)
    echo timerstart: %timerstart%
    
    set /a daymodifier=86400*((%enddate:~0,2%)-(%startdate:~0,2%))
    rem set daymodifier=86400
    echo daymodifier: %daymodifier%
    
    set /a timerstop=(((1%endtime:~0,2%-100)*60*60)+((1%endtime:~3,2%-100)*60)+(1%endtime:~6,2%-100))+%daymodifier%
    echo timerstop: %timerstop%
    
    rem =======================
    
    set /a timeseks=(%timerstop%-%timerstart%)
    echo Sekunden: %timeseks%
    
    set /a timemins=((%timerstop%-%timerstart%)/60)
    echo Minuten: %timemins%
    
    set /a timeminsseks=((((%timerstop%-%timerstart%)/60)*60)-(%timerstop%-%timerstart%))*-1
    echo Zeit: %timemins%:%timeminsseks%

    Ich werde das in den Post übernehmen als komplexere Alternative für komplexere Anwendungen 🙂

  6. Dieses Skript hat bei der Berechnung des daymodifier ein Problem mit einem Datum bei Tag: 08 bzw. 09 . Es kommt wie auch schon bei der Zeitberechnung folgende Meldung:
    „Ungültige Zahl. Numerische Konstanten sind entweder dezimale …“

    Lösung (wie oben beschrieben bei den Zeiten): eine 1 vor der Tageszahl und dann 100 abziehen.
    also so:
    set /a daymodifier=86400*((1%enddate:~0,2%-100)-(1%startdate:~0,2%-100))

  7. Super, das Skript hab ich seit ner Ewigkeit bei mir im Test laufen. Allerdings muss der daymodifier noch korrigiert werden, da trat bei mir eben das Problem mit 08 und 09 auf.

    set /a daymodifier=86400*((1%enddate:~0,2%)-(1%startdate:~0,2%))

  8. Hi,

    wenn mittlerweile auch out of topic…

    Die Konstante „1“ vor der Variable 1%starttime führt bei mir zur Fehlermeldung: Klammer fehlt und bei der Auflösung der Zeitberechnung kommt die Fehlermeldung: fehlender Operator! Lässt man jene weg, ist alles OK! Dies unter Win7 Pro.

    Error:
    set /a timerstart=((1%starttime:~0,2%-100)*60*60)+((1%starttime:~3,2%-100)*60)+(1%starttime:~6,2%-100)

    No Error:
    set /a timerstart=((%starttime:~0,2%-100)*60*60)+((%starttime:~3,2%-100)*60)+(%starttime:~6,2%-100)

    Best regards,
    Joachim

  9. REM einstellige Uhrzeiten korrigieren …
    Das funktioniert noch nicht endgültig.
    Bsp.:
    set starttime=%TIME%
    ergibt bspw. “ 9:23:45,23 (Leerzeichen an erster Stelle!)
    Damit der nachfolgende Code zuverlässig funktioniert sollte noch:
    set „starttime=%starttime: =%“ (Beachte Leerzeichen zwischen : =)
    eingesetzt werden, damit das führende Leerzeichen entfernt wird.
    Dann funktioniert auch der nachfolgende Code wieder.
    set starttime=%TIME%
    set „starttime=%starttime: =%“

    1. Hallo Volker,
      vielen Dank für den Hinweis mit den einstelligen Stundenzahlen. Ich habe das gerade nochmal getestet und tatsächlich führt dies zu einem Fehler, wenn eine einstellige Zeit vom System abgerufen wird. Mit deinem Fix funktioniert es einwandfrei. Ich habe daher meinen Code oben aktualisiert.

  10. Hallo Hannes,
    den Kommentar von Joachim vom 19.09.2015 solltest du auch noch berücksichtigen. Interessanterweise ging der Code gestern noch einwandfrei nur heute erhalte ich die Meldung mit der fehlenden Klammer. Mit dem Tipp von Joachim klappt nun aber wieder alles wunderbar (die 1 entfernen).
    Beste Grüße
    Wolfgang

  11. Hallo Hannes,
    bezüglich komplexere Lösung, 1. Skript auf dieser Seite:
    Hier fehlt zumindest unter : REM einstellige Uhrzeiten korrigieren
    set endtime=%endtime: =%
    Ich würde mir hier auch ein praxistaugliches Skript wünschen. So etwas wie einem Start, Ausführen Teil, Beendet mit Zusammenfassung (vergangene Zeit).
    Vielleicht auch ein wenig mehr: „title Beispiel: Zeitmessung“
    Liebe Grüße
    Harald

  12. Hallo,
    noch eine Korrektur bzw. Anmerkung zum Kommentar von Joachim vom 19.09.2015:
    Wenn die Uhrzeit einstellig ist, wird ein führendes Leerzeichen ausgegeben (zumindest ab Windows 10 oder Server 2012R2 ist das so). Bei den Minuten und Sekunden wird eine führende 0 ausgegeben.
    Bei den Stunden führt das dazu, dass aus “ 8″ „1 8“ wird. Daher die Fehlermeldung mit der fehlenden Klammer bzw. dem fehlenden Operator. Joachim hat korrekt geschrieben, dass hier die 1 entfernt werden muss. Allerdings muss dann auch noch die -100 entfernt werden, sonst stimmt die Rechnung nicht.
    Korrekt heißt es dann:
    set /a timerstart=(%time:~0,2%*60*60)+((1%time:~3,2%-100)*60)+(1%time:~6,2%-100)
    bzw. sinngemäß in allen anderen Codeteilen.
    Anders formuliert: Den Trick mit der 1 … -100 braucht man nur bei Minuten und Sekunden.
    SG
    Thomas

Schreibe einen Kommentar