¿Cómo mido el tiempo de ejecución de un comando en la línea de comandos de Windows?

¿Hay una forma incorporada de medir el tiempo de ejecución de un comando en la línea de comandos de Windows?

    Si usa Windows 2003 (tenga en cuenta que Windows Server 2008 y posteriores no son compatibles) puede usar el Kit de recursos de Windows Server 2003, que contiene timeit.exe que muestra las estadísticas detalladas de ejecución. Aquí hay un ejemplo, cronometrando el comando “timeit -?”:

    C:\>timeit timeit -? Invalid switch -? Usage: TIMEIT [-f filename] [-a] [-c] [-i] [-d] [-s] [-t] [-k keyname | -r keyname] [-m mask] [commandline...] where: -f specifies the name of the database file where TIMEIT keeps a history of previous timings. Default is .\timeit.dat -k specifies the keyname to use for this timing run -r specifies the keyname to remove from the database. If keyname is followed by a comma and a number then it will remove the slowest (positive number) or fastest (negative) times for that keyname. -a specifies that timeit should display average of all timings for the specified key. -i specifies to ignore non-zero return codes from program -d specifies to show detail for average -s specifies to suppress system wide counters -t specifies to tabular output -c specifies to force a resort of the data base -m specifies the processor affinity mask Version Number: Windows NT 5.2 (Build 3790) Exit Time: 7:38 am, Wednesday, April 15 2009 Elapsed Time: 0:00:00.000 Process Time: 0:00:00.015 System Calls: 731 Context Switches: 299 Page Faults: 515 Bytes Read: 0 Bytes Written: 0 Bytes Other: 298 

    Puede obtener TimeIt en el Kit de recursos de Windows 2003. Descárgalo aquí .

    Alternativamente, Windows PowerShell tiene un comando incorporado que es similar al comando “tiempo” de Bash. Se llama “Medida-Comando”. Deberá asegurarse de que PowerShell esté instalado en la máquina que lo ejecuta.

    Ejemplo de entrada:

     Measure-Command {echo hi} 

    Ejemplo de salida:

     Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 0 Ticks : 1318 TotalDays : 1.52546296296296E-09 TotalHours : 3.66111111111111E-08 TotalMinutes : 2.19666666666667E-06 TotalSeconds : 0.0001318 TotalMilliseconds : 0.1318 

    Si tu quieres

    1. Para medir el tiempo de ejecución hasta la centésima de segundo en formato (hh: mm: ss.ff)
    2. Para no tener que descargar e instalar un paquete de recursos
    3. Para parecer un gran nerd de DOS (que no)

    Intente copiar la siguiente secuencia de comandos en un nuevo archivo por lotes (por ejemplo, timecmd.bat ):

     @echo off @setlocal set start=%time% :: Runs your command cmd /c %* set end=%time% set options="tokens=1-4 delims=:.," for /f %options% %%a in ("%start%") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100 for /f %options% %%a in ("%end%") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 100 set /a hours=%end_h%-%start_h% set /a mins=%end_m%-%start_m% set /a secs=%end_s%-%start_s% set /a ms=%end_ms%-%start_ms% if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms% if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs% if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins% if %hours% lss 0 set /a hours = 24%hours% if 1%ms% lss 100 set ms=0%ms% :: Mission accomplished set /a totalsecs = %hours%*3600 + %mins%*60 + %secs% echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total) 

    Uso

    Si coloca timecmd.bat en un directorio en su ruta, puede llamarlo desde cualquier lugar como este:

     timecmd [your command] 

    P.ej

     C:\>timecmd pause Press any key to continue . . . command took 0:0:1.18 

    Si desea hacer una redirección de salida, puede citar el comando de esta manera:

     timecmd "dir c:\windows /s > nul" 

    Esto debería manejar comandos que se ejecutan desde antes hasta después de la medianoche, pero la salida será incorrecta si su comando se ejecuta durante 24 horas o más.

    Jeje, la solución más simple podría ser esta:

     echo %time% YourApp.exe echo %time% 

    Esto funciona en todas las ventanas listas para usar.


    En el caso de una aplicación que use la salida de la consola, puede ser conveniente almacenar la hora de inicio en una variable temporal:

     set startTime=%time% YourApp.exe echo Start Time: %startTime% echo Finish Time: %time% 

    Solo una pequeña expansión de la respuesta de Casey.K sobre el uso del Measure-Command de PowerShell :

    1. Puede invocar PowerShell desde el símbolo del sistema estándar, como este:

       powershell -Command "Measure-Command {echo hi}" 
    2. Esto comerá la salida estándar, pero puede evitar eso al agregar | Out-Default | Out-Default como este de PowerShell:

       Measure-Command {echo hi | Out-Default} 

      O desde un símbolo del sistema:

       powershell -Command "Measure-Command {echo hi | Out-Default}" 

    Por supuesto, puede envolver esto en un archivo de script *.ps1 o *.bat .

    El one-liner que uso en Windows Server 2008 R2 es:

     cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!" 

    Siempre que mycommand no requiera comillas (que se atornilla con el procesamiento de comillas de cmd). El /v:on es para permitir que los dos valores TIME diferentes sean evaluados independientemente en vez de una vez en la ejecución del comando.

    Si tiene una ventana de comando abierta y llama los comandos manualmente, puede mostrar una marca de tiempo en cada aviso, por ejemplo

     prompt $d $t $_$P$G 

    Te da algo como:

    23.03.2009 15:45:50,77

    C:\>

    Si tiene un pequeño script por lotes que ejecuta sus comandos, tenga una línea vacía antes de cada comando, por ejemplo

    (línea vacía)

    myCommand.exe

    (siguiente línea vacía)

    myCommand2.exe

    Puede calcular el tiempo de ejecución para cada comando según la información de tiempo en el aviso. Lo mejor sería probablemente canalizar la salida a un archivo de texto para su posterior análisis:

     MyBatchFile.bat > output.txt 

    Como otros recomiendan instalar cosas como freeware y PowerShell, también puedes instalar Cygwin , que te da acceso a muchos comandos básicos de Unix, como el tiempo :

     abe@abe-PC:~$ time sleep 5 real 0m5.012s user 0m0.000s sys 0m0.000s 

    No estoy seguro de cuánto overhead agrega Cygwin.

    No es tan elegante como algunas de las funciones en Unix, pero crea un archivo cmd que se ve así:

     @echo off time < nul yourexecutable.exe > c:\temp\output.txt time < nul rem on newer windows system you can try time /T 

    Eso mostrará los tiempos de inicio y finalización de esta manera:

     The current time is: 10:31:57.92 Enter the new time: The current time is: 10:32:05.94 Enter the new time: 

    Yo uso freeware llamado “GS Timer”.

    Simplemente haga un archivo por lotes como este:

     timer yourapp.exe timer /s 

    Si necesita un conjunto de veces, simplemente canalice la salida de los temporizadores en un archivo .txt.

    Puede obtenerlo aquí: Gammadyne’s Free DOS Utilities


    La resolución es 0.1 segundos.

    Estoy usando Windows XP y por alguna razón timeit.exe no funciona para mí. Encontré otra alternativa: PTIME. Esto funciona muy bien

    http://www.pc-tools.net/win32/ptime/

    Ejemplo –

     C:\> ptime ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/ Copyright(C) 2002, Jem Berkes  Syntax: ptime command [arguments ...] ptime will run the specified command and measure the execution time (run time) in seconds, accurate to 5 millisecond or better. It is an automatic process timer, or program timer. C:\> ptime cd ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/ Copyright(C) 2002, Jem Berkes  === cd === C:\ Execution time: 0.015 s 

    Siempre que no dure más de 24 horas …

     @echo off set starttime=%TIME% set startcsec=%STARTTIME:~9,2% set startsecs=%STARTTIME:~6,2% set startmins=%STARTTIME:~3,2% set starthour=%STARTTIME:~0,2% set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%) :TimeThis ping localhost set endtime=%time% set endcsec=%endTIME:~9,2% set endsecs=%endTIME:~6,2% set endmins=%endTIME:~3,2% set endhour=%endTIME:~0,2% if %endhour% LSS %starthour% set /a endhour+=24 set /a endtime=(%endhour%*60*60*100)+(%endmins%*60*100)+(%endsecs%*100)+(%endcsec%) set /a timetaken= ( %endtime% - %starttime% ) set /a timetakens= %timetaken% / 100 set timetaken=%timetakens%.%timetaken:~-2% echo. echo Took: %timetaken% sec. 

    También hay TimeMem (marzo de 2012):

    Esta es una utilidad de Windows que ejecuta un progtwig y muestra su tiempo de ejecución, uso de memoria y estadísticas de E / S. Es similar en funcionalidad a la utilidad de tiempo de Unix.

    Este es un trazador de líneas único que evita la expansión retardada , lo que podría alterar ciertos comandos:

     cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ " 

    La salida es algo así como:

     14:30:27.58$ ... 14:32:43.17$ rem/ 

    Para pruebas a largo plazo, reemplace $T por $D, $T y %TIME% por %DATE%, %TIME% para incluir la fecha.

    Para usar esto dentro de un archivo por lotes , reemplace %Z por %%Z


    Actualizar

    Aquí hay una línea mejorada (sin expansión retardada también):

     cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt" 

    El resultado es similar a esto:

     2015/09/01, 14:30:27.58$ rem/ ... 2015/09/01, 14:32:43.17$ prompt 

    Este enfoque no incluye el proceso de crear un nuevo cmd en el resultado, ni incluye los prompt .

    Aquí hay un

    Versión del temporizador Postfix:

    Ejemplo de uso:

    tiempo de espera 1 | TimeIt.cmd

     Execution took ~969 milliseconds. 

    Copie y pegue esto en algún editor como por ejemplo Notepad ++ y guárdelo como TimeIt.cmd :

     :: --- TimeIt.cmd ---- @echo off setlocal enabledelayedexpansion call :ShowHelp :: Set pipeline initialization time set t1=%time% :: Wait for stdin more :: Set time at which stdin was ready set t2=!time! :: Calculate difference Call :GetMSeconds Tms1 t1 Call :GetMSeconds Tms2 t2 set /a deltaMSecs=%Tms2%-%Tms1% echo Execution took ~ %deltaMSecs% milliseconds. endlocal goto :eof :GetMSeconds Call :Parse TimeAsArgs %2 Call :CalcMSeconds %1 %TimeAsArgs% goto :eof :CalcMSeconds set /a %1= (%2 * 3600*1000) + (%3 * 60*1000) + (%4 * 1000) + (%5) goto :eof :Parse :: Mask time like " 0:23:29,12" set %1=!%2: 0=0! :: Replace time separators with " " set %1=!%1::= ! set %1=!%1:.= ! set %1=!%1:,= ! :: Delete leading zero - so it'll not parsed as octal later set %1=!%1: 0= ! goto :eof :ShowHelp echo %~n0 V1.0 [Dez 2015] echo. echo Usage: ^ ^| %~nx0 echo. echo Wait for pipe getting ready... :) echo (Press Ctrl+Z ^ to Cancel) goto :eof 

    ^ – Basado en la versión de ‘Daniel Sparks’

    En caso de que alguien más haya venido aquí en busca de una respuesta a esta pregunta, hay una función de API de Windows llamada GetProcessTimes() . No parece demasiado trabajo escribir un pequeño progtwig en C que inicie el comando, realice esta llamada y devuelva los tiempos del proceso.

    Este es un comentario / edición del buen timecmd.bat Luke Sampson y respuesta a

    Por alguna razón, esto solo me da salida en segundos enteros … lo cual para mí es inútil. Quiero decir que ejecuto timecmd pausa, y siempre resulta en 1.00 segundos, 2.00 segundos, 4.00 segundos … ¡incluso 0.00 segundos! Windows 7. – Camilo Martin 25 de septiembre de 13 a 16:00 ”

    En algunas configuraciones, los delimitadores pueden diferir. El siguiente cambio debería cubrir al menos la mayoría de los países occidentales.

     set options="tokens=1-4 delims=:,." (added comma) 

    El %time% milisegundos funciona en mi sistema después de agregar ese ‘,’

    (* porque el sitio no permite comentarios adicionales y no mantiene un buen registro de identidad, aunque siempre uso el mismo correo electrónico de invitado, que combinado con ipv6 ip y huella digital del navegador debería ser suficiente para identificar de manera única sin contraseña)

     @echo off & setlocal set start=%time% REM Do stuff to be timed here. REM Alternatively, uncomment the line below to be able to REM pass in the command to be timed when running this script. REM cmd /c %* set end=%time% REM Calculate time taken in seconds, to the hundredth of a second. REM Assumes start time and end time will be on the same day. set options="tokens=1-4 delims=:." for /f %options% %%a in ("%start%") do ( set /a start_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)" set /a start_hs=100%%d %% 100 ) for /f %options% %%a in ("%end%") do ( set /a end_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)" set /a end_hs=100%%d %% 100 ) set /as=%end_s%-%start_s% set /a hs=%end_hs%-%start_hs% if %hs% lss 0 ( set /as=%s%-1 set /a hs=100%hs% ) if 1%hs% lss 100 set hs=0%hs% echo. echo Time taken: %s%.%hs% secs echo. 

    La siguiente secuencia de comandos usa solo “cmd.exe” y genera la cantidad de milisegundos desde el momento en que se crea una interconexión hasta el momento en que finaliza el proceso anterior a la secuencia de comandos. es decir, escriba su comando y canalice el script. Ejemplo: “timeout 3 | runtime.cmd” debería producir algo así como “2990”. Si necesita tanto la salida de tiempo de ejecución como la salida stdin, redireccione stdin antes de que la tubería ex: “dir / s 1> temp.txt | runtime.cmd” descargue la salida del comando “dir” a “temp.txt” e imprimiría el tiempo de ejecución a la consola.

     :: --- runtime.cmd ---- @echo off setlocal enabledelayedexpansion :: find target for recursive calls if not "%1"=="" ( shift /1 goto :%1 exit /b ) :: set pipeline initialization time set t1=%time% :: wait for stdin more > nul :: set time at which stdin was ready set t2=!time! ::parse t1 set t1=!t1::= ! set t1=!t1:.= ! set t1=!t1: 0= ! :: parse t2 set t2=!t2::= ! set t2=!t2:.= ! set t2=!t2: 0= ! :: calc difference pushd %~dp0 for /f %%i in ('%0 calc !t1!') do for /f %%j in ('%0 calc !t2!') do ( set /at=%%j-%%i echo !t! ) popd exit /b goto :eof :calc set /at=(%1*(3600*1000))+(%2*(60*1000))+(%3*1000)+(%4) echo !t! goto :eof endlocal 

    La respuesta de driblio puede hacerse un poco más corta (aunque no mucho legible)

     @echo off :: Calculate the start timestamp set _time=%time% set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2% set /a _started=_hours*60*60*100+_min*60*100+_sec*100+_cs :: yourCommandHere :: Calculate the difference in cSeconds set _time=%time% set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2% set /a _duration=_hours*60*60*100+_min*60*100+_sec*100+_cs-_started :: Populate variables for rendering (100+ needed for padding) set /a _hours=_duration/60/60/100,_min=100+_duration/60/100%%60,_sec=100+(_duration/100%%60%%60),_cs=100+_duration%%100 echo Done at: %_time% took : %_hours%:%_min:~-2%:%_sec:~-2%.%_cs:~-2% ::prints something like: ::Done at: 12:37:53,70 took: 0:02:03.55 

    Para la observación de Luke Sampson, esta versión es octal segura, aunque la tarea debe completarse en 24 horas.

    1. En el directorio donde está tu progtwig, escribe notepad mytimer.bat , notepad mytimer.bat clic en ‘yes’ para crear un nuevo archivo.

    2. Pegue el siguiente código, reemplace YourApp.exe con su progtwig y luego guárdelo.

       @echo off date /t time /t YourApp.exe date /t time /t 
    3. Escriba mytimer.bat en la línea de comando y luego presione Entrar.

    Process Explorer mostrará el tiempo del kernel, el tiempo del usuario y el tiempo de pared (y muchas otras cosas) siempre que haga clic en el proceso antes de que salga. No es una herramienta de línea de comandos, pero de todos modos es inmensamente útil.

    La siguiente secuencia de comandos emula * nix epoch time, pero es local y regional. Debe manejar casos de borde de calendario incluyendo años bisiestos. Si Cygwin está disponible, los valores de época se pueden comparar especificando la opción Cygwin .

    Estoy en EST y la diferencia reportada es de 4 horas, lo cual es relativamente correcto. Hay algunas soluciones interesantes para eliminar el TZ y las dependencias regionales, pero nada trivial que haya notado.

     @ECHO off SETLOCAL EnableDelayedExpansion :: :: Emulates local epoch seconds :: :: Call passing local date and time CALL :SECONDS "%DATE%" "%TIME%" IF !SECONDS! LEQ 0 GOTO END :: Not testing - print and exit IF NOT "%~1"=="cygwin" ( ECHO !SECONDS! GOTO END ) :: Call on Cygwin to get epoch time FOR /F %%c IN ('C:\cygwin\bin\date +%%s') DO SET EPOCH=%%c :: Show the results ECHO Local Seconds: !SECONDS! ECHO Epoch Seconds: !EPOCH! :: Calculate difference between script and Cygwin SET /A HOURS=(!EPOCH!-!SECONDS!)/3600 SET /A FRAC=(!EPOCH!-!SECONDS!)%%3600 :: Delta hours shown reflect TZ ECHO Delta Hours: !HOURS! Remainder: !FRAC! GOTO END :SECONDS SETLOCAL EnableDelayedExpansion :: Expecting values from caller SET DATE=%~1 SET TIME=%~2 :: Emulate Unix epoch time without considering TZ SET "SINCE_YEAR=1970" :: Regional constraint! Expecting date and time in the following formats: :: Sun 03/08/2015 Day MM/DD/YYYY :: 20:04:53.64 HH:MM:SS SET VALID_DATE=0 ECHO !DATE! | FINDSTR /R /C:"^... [0-9 ][0-9]/[0-9 ][0-9]/[0-9][0-9][0-9][0-9]" > nul && SET VALID_DATE=1 SET VALID_TIME=0 ECHO !TIME! | FINDSTR /R /C:"^[0-9 ][0-9]:[0-9 ][0-9]:[0-9 ][0-9]" > nul && SET VALID_TIME=1 IF NOT "!VALID_DATE!!VALID_TIME!"=="11" ( IF !VALID_DATE! EQU 0 ECHO Unsupported Date value: !DATE! 1>&2 IF !VALID_TIME! EQU 0 ECHO Unsupported Time value: !TIME! 1>&2 SET SECONDS=0 GOTO SECONDS_END ) :: Parse values SET "YYYY=!DATE:~10,4!" SET "MM=!DATE:~4,2!" SET "DD=!DATE:~7,2!" SET "HH=!TIME:~0,2!" SET "NN=!TIME:~3,2!" SET "SS=!TIME:~6,2!" SET /A YEARS=!YYYY!-!SINCE_YEAR! SET /A DAYS=!YEARS!*365 :: Bump year if after February - want leading zeroes for this test IF "!MM!!DD!" GEQ "0301" SET /A YEARS+=1 :: Remove leading zeros that can cause octet probs for SET /A FOR %%r IN (MM,DD,HH,NN,SS) DO ( SET "v=%%r" SET "t=!%%r!" SET /AN=!t:~0,1!0 IF 0 EQU !N! SET "!v!=!t:~1!" ) :: Increase days according to number of leap years SET /A DAYS+=(!YEARS!+3)/4-(!SINCE_YEAR!%%4+3)/4 :: Increase days by preceding months of current year FOR %%n IN (31:1,28:2,31:3,30:4,31:5,30:6,31:7,31:8,30:9,31:10,30:11) DO ( SET "n=%%n" IF !MM! GTR !n:~3! SET /A DAYS+=!n:~0,2! ) :: Multiply and add it all together SET /A SECONDS=(!DAYS!+!DD!-1)*86400+!HH!*3600+!NN!*60+!SS! :SECONDS_END ENDLOCAL & SET "SECONDS=%SECONDS%" GOTO :EOF :END ENDLOCAL 

    Aquí está mi método, sin conversión y sin ms. Sin embargo, es útil para determinar la duración de la encoding (limitada a 24 horas):

     @echo off :start REM Start time storage set ST=%time% echo Process started at %ST% echo. echo. REM Your commands REM Your commands REM Your commands :end REM Start Time Definition for /f "tokens=1-3 delims=:" %%a in ("%ST%") do set /a h1=%%a & set /a m1=%%b & set /a s1=%%c REM End Time Definition for /f "tokens=1-3 delims=:" %%a in ("%TIME%") do set /a h2=%%a & set /a m2=%%b & set /a s2=%%c REM Difference set /a h3=%h2%-%h1% & set /a m3=%m2%-%m1% & set /a s3=%s2%-%s1% REM Time Adjustment if %h3% LSS 0 set /a h3=%h3%+24 if %m3% LSS 0 set /a m3=%m3%+60 & set /a h3=%h3%-1 if %s3% LSS 0 set /a s3=%s3%+60 & set /a m3=%m3%-1 echo Start : %ST% echo End : %time% echo. echo Total : %h3%:%m3%:%s3% echo. pause 

    Usar un sub para regresar el tiempo en centésimas de segundo

     ::tiemeit.cmd @echo off Setlocal EnableDelayedExpansion call :clock ::call your_command or more > null to pipe this batch after your_command call :clock echo %timed% pause goto:eof :clock if not defined timed set timed=0 for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( set /A timed = "(((1%%a - 100) * 60 + (1%%b - 100)) * 60 + (1%%c - 100)) * 100 + (1%%d - 100)- %timed%" ) goto:eof 

    TEMPORIZADOR “Lean and Mean” con formato regional, 24 horas y soporte mixto de entrada
    Adaptando el cuerpo del método de sustitución de Aacini , sin IF, solo uno FOR (mi arreglo regional)

    1: archivo timer.bat colocado en algún lugar en% PATH% o el directorio actual

     @echo off & rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof (if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n) set "TE=!timer_end:%DE%=%%100)*100+1!" & set "TS=!timer_set:%DS%=%%100)*100+1!" set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!" set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100" set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value! endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof 

    Uso:
    timer & echo start_cmds & timeout / t 3 & echo end_cmds & timer
    temporizador y temporizador “23: 23: 23,00”
    temporizador “23: 23: 23,00” y temporizador
    temporizador “13.23.23,00” y temporizador “03: 03: 03.00”
    timer & timer “0: 00: 00.00” no & cmd / v: on / c echo hasta la medianoche =! timer_end!
    La entrada ahora puede mezclarse, para esos cambios improbables, pero posibles cambios de formato de tiempo durante la ejecución

    2: Función : temporizador incluido con el script por lotes (uso de muestra a continuación):

     @echo off set "TIMER=call :timer" & rem short macro echo. echo EXAMPLE: call :timer timeout /t 3 >nul & rem Any process here.. call :timer echo. echo SHORT MACRO: %TIMER% & timeout /t 1 & %TIMER% echo. echo TEST INPUT: set "start=22:04:04.58" set "end=04.22.44,22" echo %start% ~ start & echo %end% ~ end call :timer "%start%" call :timer "%end%" echo. %TIMER% & %TIMER% "00:00:00.00" no echo UNTIL MIDNIGHT: %timer_end% echo. pause exit /b 

    :: para probarlo, copiar y pegar secciones de códigos tanto arriba como debajo

     rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support :timer Usage " call :timer [input - optional] [no - optional]" :i Result printed on second call, saved to timer_end if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof (if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n) set "TE=!timer_end:%DE%=%%100)*100+1!" & set "TS=!timer_set:%DS%=%%100)*100+1!" set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!" set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100" set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value! endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof 

    CE,DE and CS,DS stand for colon end, dot end and colon set, dot set – used for mixed format support

    For Luke Sampson’s nice script, the corrections for negative values should be done in the reverse order since they can make a previously 0 value go negative.

    Take for example a time were the initial subtraction gives 1 hour, 0 min. and -29 seconds. As done in the post the result will be 1 hour, -1 min, and 31 seconds. If the seconds are corrected before minutes and minutes before hours you instead get 31 seconds, 59 min, 0 hours.

    my code gives you the running time in milliseconds, up to 24 hrs, it is locale insensitive, and accounts for negative values if code runs through midnight. it uses delayed expansion, and should be saved in a cmd/bat file.

    before your code:

     SETLOCAL EnableDelayedExpansion for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I set /a t1 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t1=!t1!%t:~15,3% 

    after your code:

     for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I set /a t2 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t2=!t2!%t:~15,3% set /a t2-=t1 && if !t2! lss 0 set /a t2+=24*3600000 

    if you want running time in HH:mm:ss.000 format, add:

     set /a "h=t2/3600000,t2%%=3600000,m=t2/60000,t2%%=60000" && set t2=00000!t2!&& set t2=!t2:~-5! if %h% leq 9 (set h=0%h%) && if %m% leq 9 (set m=0%m%) set t2=%h%:%m%:%t2:~0,2%.%t2:~2,3% ENDLOCAL 

    variable t2 holds your running time, you can echo %t2% to display it.