¿Existe una forma integrada de medir el tiempo de ejecución de un comando en la línea de comandos de Windows?
¿Existe una forma integrada de medir el tiempo de ejecución de un comando en la línea de comandos de Windows?
Respuestas:
Si usa Windows 2003 (tenga en cuenta que Windows Server 2008 y versiones posteriores no son compatibles) puede usar el Kit de recursos de Windows Server 2003, que contiene timeit.exe que muestra 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 "time" de Bash. Se llama "Medida-Comando". Deberá asegurarse de que PowerShell esté instalado en la máquina que lo ejecuta.
Entrada de ejemplo:
Measure-Command {echo hi}
Salida de ejemplo:
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
.exe
en el directorio actual, utilice la siguiente: Measure-Command { .\your.exe }
. PowerShell aparentemente no ejecuta cosas a pwd
menos que se le indique explícitamente.
<stdout>
los resultados del comando encerrado entre llaves!
Si tu quieres
Intente copiar el siguiente script 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 los 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.
timecmd pause
, y siempre resulta en 1.00 segundos, 2.00 segundos, 4.00 segundos ... ¡incluso 0.00 segundos! Windows 7.
delims=:.
a delims=:.,
, y luego debería funcionar "en todos los ámbitos".
set start=10:10:10.10
set end=10:11:10.09
Y generará: command took 0:1:-1.99 (59.99s total)
Debe invertir el orden de las 4 líneas que hacen comparaciones "lss 0", de modo que el acarreo progrese correctamente de dígitos sexagesimales bajos a altos. Entonces la salida se convierte en: command took 0:0:59.99 (59.99s total)
Jeje, la solución más simple podría ser esta:
echo %time%
YourApp.exe
echo %time%
Esto funciona en cada Windows fuera de la caja.
En el caso de una aplicación que utiliza la salida de la consola, puede ser conveniente almacenar el tiempo de inicio en una variable temporal:
set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%
set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time%
(Lo siento, no pude obtener nuevas líneas en el comentario)
set
para hacer los cálculos. ;-)
Oh, espera, no importa, ya lo hiciste a continuación.
Solo una pequeña expansión de la respuesta de Casey.K sobre el uso Measure-Command
de PowerShell :
Puede invocar PowerShell desde el símbolo del sistema estándar, como este:
powershell -Command "Measure-Command {echo hi}"
Esto consumirá el resultado estándar, pero puede evitarlo agregando | Out-Default
así desde PowerShell:
Measure-Command {echo hi | Out-Default}
O desde un símbolo del sistema:
powershell -Command "Measure-Command {echo hi | Out-Default}"
Por supuesto, puedes envolver esto en un archivo de script *.ps1
o *.bat
.
measureTime.bat "c:\program files\some dir\program.exe"
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
objetivo es permitir que los dos valores TIME diferentes se evalúen de forma independiente en lugar de una vez en la ejecución del comando.
^
en cmd (como ^"
)
cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
.
echo %time% & *mycommand* & call echo %^time%
. Ver también esta respuesta .
cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
Si tiene una ventana de comandos abierta y llama a los comandos manualmente, puede mostrar una marca de tiempo en cada solicitud, 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 de cada comando por la información de tiempo en la solicitud. Lo mejor probablemente sería 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 puede instalar Cygwin , que le daría 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 agrega Cygwin.
No es tan elegante como algunas de las funciones de Unix, pero crea un archivo cmd que se vea 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:
time
tiene una /t
opción que solo muestra la hora actual del sistema, sin pedirle que ingrese una nueva hora. Sin embargo, cuando lo hace, solo muestra horas y minutos, lo que puede no ser lo suficientemente bueno para algunos usos. (Ver la respuesta de John Snow a esta pregunta).
time /T
¡solo se puede usar si el proceso se ejecuta durante varios minutos! time < nul
Es más feo pero más preciso.
echo %time%
que proporciona el mismo formato y precisión time < nul
, pero evita el Enter the new time:
resultado ...
wmic os get LocalDateTime
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 del temporizador / s en un archivo .txt.
Puede obtenerlo aquí: las utilidades gratuitas de DOS de Gammadyne
La resolución es de 0.1 segundos.
Estoy usando Windows XP y por alguna razón timeit.exe no me funciona. 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 <jberkes@pc-tools.net>
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 <jberkes@pc-tools.net>
=== cd ===
C:\
Execution time: 0.015 s
También está TimeMem (marzo de 2012):
Esta es una utilidad de Windows que ejecuta un programa 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 Unix.
Mientras 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.
Aquí hay un
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: ^<Command^> ^| %~nx0
echo.
echo Wait for pipe getting ready... :)
echo (Press Ctrl+Z ^<Enter^> to Cancel)
goto :eof
^ - Basado en la versión 'Daniel Sparks'
Una alternativa al tiempo de medición es simplemente "Get-Date". No tiene esa molestia con el envío de salida, etc.
$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start
Salida:
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 506
Ticks : 15060003
TotalDays : 1.74305590277778E-05
TotalHours : 0.000418333416666667
TotalMinutes : 0.025100005
TotalSeconds : 1.5060003
TotalMilliseconds : 1506.0003
Esta es una línea que evita la expansión retrasada , 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 las pruebas a largo plazo reemplazan $T
por $D, $T
y %TIME%
por %DATE%, %TIME%
incluir la fecha.
Para usar esto dentro de un archivo por lotes , reemplácelo %Z
por %%Z
.
Aquí hay una línea mejorada (sin expansión tardía 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 instanciar una nueva cmd
en el resultado, ni incluye los prompt
comandos.
Dependiendo de la versión de Windows que esté usando, solo ejecutarlo bash
lo pondrá en modo Bash. Esto le permitirá usar un montón de comandos que no están disponibles en PowerShell directamente (como el time
comando). Sincronizar su comando ahora es tan fácil como ejecutar:
# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>
Nota: Puede salir fácilmente del modo Bash y volver a su shell principal ejecutando
exit
mientras está en modo Bash.
Esto funcionó perfectamente para mí (Windows 10) después de probar otros métodos (como Measure-Command
) que a veces producen estadísticas no deseadas. Espero que esto también funcione para ti.
En caso de que alguien más haya venido aquí buscando una respuesta a esta pregunta, hay una función API de Windows llamada GetProcessTimes()
. No parece demasiado trabajo escribir un pequeño programa en C que inicie el comando, realice esta llamada y devuelva los tiempos de proceso.
Este es un comentario / edición a Luke Sampson agradable timecmd.bat
y responde a
Por alguna razón, esto solo me da salida en segundos completos ... lo que para mí es inútil. Quiero decir que ejecuto pausa timecmd, y siempre resulta en 1.00 segundos, 2.00 segundos, 4.00 segundos ... ¡incluso 0.00 segundos! Windows 7. - Camilo Martin Sep 25 '13 a las 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)
Los %time%
milisegundos funcionan en mi sistema después de agregar que ','
(* porque el sitio no permite comentarios anónimos y no mantiene un buen seguimiento de la identidad a pesar de que siempre uso el mismo correo electrónico de invitado que combinado con ipv6 ip y la huella digital del navegador deberían ser suficientes para identificarme sin contraseña)
Aquí está mi método, sin conversión y sin ms. Es útil para determinar las duraciones de codificación (aunque limitado 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
@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 /a s=%end_s%-%start_s%
set /a hs=%end_hs%-%start_hs%
if %hs% lss 0 (
set /a s=%s%-1
set /a hs=100%hs%
)
if 1%hs% lss 100 set hs=0%hs%
echo.
echo Time taken: %s%.%hs% secs
echo.
El siguiente script usa solo "cmd.exe" y genera el número de milisegundos desde el momento en que se crea una canalización hasta el momento en que se cierra el proceso que precede al script. es decir, escriba su comando y canalice el al script. Ejemplo: "timeout 3 | runtime.cmd" debería producir algo como "2990". Si necesita tanto la salida de tiempo de ejecución como la salida de stdin, redirija el stdin antes de la tubería, por ejemplo: "dir / s 1> temp.txt | runtime.cmd" volcaría la salida del comando "dir" a "temp.txt" e imprimiría el tiempo de ejecución en 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 /a t=%%j-%%i
echo !t!
)
popd
exit /b
goto :eof
:calc
set /a t=(%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 muy 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 el comentario de Luke Sampson, esta versión es segura para los ojos, aunque la tarea debe completarse en 24 horas.
set _time=%time: =0%
soluciona el problema de la hora de un solo dígito: reemplácelo en ambos lugares.
En el directorio donde está su programa, escriba notepad mytimer.bat
, haga clic en 'sí' para crear un nuevo archivo.
Pegue el código a continuación, reemplácelo YourApp.exe
con su programa, luego guárdelo.
@echo off
date /t
time /t
YourApp.exe
date /t
time /t
Escriba mytimer.bat
la línea de comando y luego presione Entrar.
mi código le da el tiempo de ejecución en milisegundos, hasta 24 horas, es insensible a la configuración regional y tiene en cuenta los valores negativos si el código se ejecuta hasta la medianoche. usa expansión demorada y debe guardarse en un archivo cmd / bat.
antes de su código:
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%
después de tu código:
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
si desea tiempo de ejecución en formato HH: mm: ss.000, agregue:
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
contiene su tiempo de ejecución, puede echo %t2%
mostrarlo.
Una vez que Perl haya instalado la solución de contrataciones disponible, ejecute:
C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result
STDERR viene antes de los segundos medidos
#!/usr/bin/perl -w
use Time::HiRes qw();
my $T0 = [ Time::HiRes::gettimeofday ];
my $stdout = `@ARGV`;
my $time_elapsed = Time::HiRes::tv_interval( $T0 );
print $time_elapsed, "\n";
print $stdout;
Usando un sub para devolver 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
TIMER "Lean and Mean" con formato regional, 24 horas y soporte de entrada mixta
Adaptación de Aacini cuerpo del método de sustitución , sin IF, solo uno FOR (mi solución 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
timer & timer "23: 23: 23,00"
timer "23: 23: 23,00" y timer
timer "13.23.23,00" y timer "03: 03: 03.00"
temporizador y temporizador "0: 00: 00.00" no y cmd / v: on / c echo hasta medianoche =! Timer_end!
La entrada ahora se puede mezclar, para aquellos cambios de formato de tiempo improbables pero posibles 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, copie y pegue las secciones de código arriba y abajo
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 y CS, DS significan punto final, punto final y conjunto de dos puntos, conjunto de puntos: se utiliza para compatibilidad con formatos mixtos
El siguiente script emula * nix epoch time, pero es local y regional. Debe manejar los casos de borde de calendario, incluidos los años bisiestos. Si Cygwin está disponible, los valores de época se pueden comparar especificando Cygwin opción .
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 no noté nada trivial.
@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 /A N=!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
@echo off
setlocal enableextensions
REM set start time env var
FOR /F "tokens=* USEBACKQ" %%F IN (`php -r "echo microtime(true);"`) DO ( SET start_time=%%F )
## PUT_HERE_THE_COMMAND_TO_RUN ##
REM echo elapsed time
php -r "echo 'elapsed: ' . (round(microtime(true) - trim(getenv('start_time')), 2)) . ' seconds' . mb_convert_encoding(' ', 'UTF-8', 'HTML-ENTITIES');"
sin necesidad de cygwin o utilidades no confiables. Útil cuando PHP está disponible localmente
la precisión y el formato de salida se pueden ajustar fácilmente
la misma idea se puede portar para PowerShell