Existe uma maneira interna de medir o tempo de execução de um comando na linha de comando do Windows?
Existe uma maneira interna de medir o tempo de execução de um comando na linha de comando do Windows?
Respostas:
Se você estiver usando o Windows 2003 (observe que o Windows Server 2008 e versões posteriores não são suportadas), poderá usar o Windows Server 2003 Resource Kit, que contém timeit.exe que exibe estatísticas detalhadas de execução. Aqui está um exemplo, cronometrando o 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
Você pode obter o TimeIt no Windows 2003 Resource Kit. Faça o download aqui .
Como alternativa, o Windows PowerShell possui um comando interno semelhante ao comando "time" do Bash. É chamado "Medida-Comando". Você precisará garantir que o PowerShell esteja instalado na máquina que o executa.
Exemplo de entrada:
Measure-Command {echo hi}
Saída de exemplo:
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
no diretório atual, use o seguinte: Measure-Command { .\your.exe }
. Aparentemente, o PowerShell não executa as coisas, a pwd
menos que seja explicitamente instruído.
<stdout>
resultados do comando entre colchetes!
Se você quiser
Tente copiar o seguinte script em um novo arquivo em lotes (por exemplo, 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
Se você colocar timecmd.bat em um diretório em seu caminho, poderá chamá-lo de qualquer lugar como este:
timecmd [your command]
Por exemplo
C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18
Se você deseja fazer o redirecionamento de saída, pode citar o comando da seguinte maneira:
timecmd "dir c:\windows /s > nul"
Isso deve lidar com comandos que são executados antes e depois da meia-noite, mas a saída estará errada se o seu comando for executado por 24 horas ou mais.
timecmd pause
, e sempre resulta em 1,00 seg, 2,00 seg, 4,00 seg ... até 0,00 seg! Windows 7.
delims=:.
para delims=:.,
e, em seguida, ele deve funcionar "de maneira geral".
set start=10:10:10.10
set end=10:11:10.09
E ele produzirá: command took 0:1:-1.99 (59.99s total)
Você deve reverter a ordem das 4 linhas que fazem comparações "lss 0", para que o transporte progrida corretamente dos dígitos sexagesimais mínimos para os altos. Em seguida, a saída se torna: command took 0:0:59.99 (59.99s total)
Hehe, a solução mais simples pode ser a seguinte:
echo %time%
YourApp.exe
echo %time%
Isso funciona em todos os Windows prontos para uso.
No caso de um aplicativo usar saída do console, pode ser conveniente armazenar o horário de início em uma variável temporária:
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%
(Desculpe, não pude obter novas linhas no comentário)
set
para fazer as contas. ;-)
Oh espera, deixa pra lá, você já fez isso abaixo.
Apenas uma pequena expansão da resposta da Casey.K sobre o uso Measure-Command
do PowerShell :
Você pode invocar o PowerShell no prompt de comando padrão, assim:
powershell -Command "Measure-Command {echo hi}"
Isso consumirá a saída padrão, mas você pode impedir isso adicionando | Out-Default
assim do PowerShell:
Measure-Command {echo hi | Out-Default}
Ou em um prompt de comando:
powershell -Command "Measure-Command {echo hi | Out-Default}"
Obviamente, você pode agrupar isso em um arquivo de script *.ps1
ou *.bat
.
measureTime.bat "c:\program files\some dir\program.exe"
A linha única que eu uso no Windows Server 2008 R2 é:
cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"
Enquanto mycommand não requer aspas (que parafusos com processamento citação de cmd). O /v:on
objetivo é permitir que os dois valores TIME diferentes sejam avaliados independentemente, e não uma vez na execução do comando.
^
em cmd (like ^"
)
cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
.
echo %time% & *mycommand* & call echo %^time%
. Veja também esta resposta .
cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
Se você tiver uma janela de comando aberta e chamar os comandos manualmente, poderá exibir um carimbo de data / hora em cada prompt, por exemplo
prompt $d $t $_$P$G
Dá-lhe algo como:
23.03.2009 15:45:50,77
C:\>
Se você tiver um pequeno script em lote que execute seus comandos, tenha uma linha vazia antes de cada comando, por exemplo
(linha vazia)
myCommand.exe
(próxima linha vazia)
myCommand2.exe
Você pode calcular o tempo de execução de cada comando pelas informações de tempo no prompt. O melhor seria provavelmente canalizar a saída para um arquivo de texto para análise posterior:
MyBatchFile.bat > output.txt
Como outros recomendam a instalação de coisas como freeware e PowerShell, você também pode instalar o Cygwin , que daria acesso a muitos comandos básicos do Unix, como o tempo :
abe@abe-PC:~$ time sleep 5
real 0m5.012s
user 0m0.000s
sys 0m0.000s
Não tenho certeza de quanto Cygwin sobrecarga acrescenta.
Não é tão elegante quanto algumas das funcionalidades do Unix, mas cria um arquivo cmd que se parece com:
@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T
Isso exibirá os horários de início e término da seguinte forma:
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
possui uma /t
opção que apenas exibe a hora atual do sistema, sem solicitar que você insira uma nova hora. No entanto, quando você faz isso, ele exibe apenas horas e minutos, o que pode não ser bom o suficiente para alguns usos. (Resposta See de John Snow a esta pergunta.)
time /T
é utilizável apenas se o processo for executado por vários minutos! time < nul
é mais feio, mas mais preciso.
echo %time%
que fornece o mesmo formato e precisão como time < nul
, mas você evitar a Enter the new time:
saída ...
wmic os get LocalDateTime
Eu uso o freeware chamado "GS Timer".
Basta criar um arquivo em lotes como este:
timer
yourapp.exe
timer /s
Se você precisar de um conjunto de horários, basta canalizar a saída do timer / s em um arquivo .txt.
Você pode obtê-lo aqui: Utilitários gratuitos para Gammadyne
A resolução é de 0,1 segundos.
Estou usando o Windows XP e, por algum motivo, o timeit.exe não funciona para mim. Encontrei outra alternativa - PTIME. Isso funciona muito bem.
http://www.pc-tools.net/win32/ptime/
Exemplo -
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
Há também o TimeMem (março de 2012):
Este é um utilitário do Windows que executa um programa e exibe seu tempo de execução, uso de memória e estatísticas de E / S. É semelhante em funcionalidade ao utilitário de tempo Unix.
Contanto que não dure mais 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.
Aqui está um
Exemplo de uso:
timeout 1 | TimeIt.cmd
Execution took ~969 milliseconds.
Copie e cole isso em algum editor como, por exemplo, o Notepad ++ e salve-o 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
^ - Baseado na versão 'Daniel Sparks'
Uma alternativa para medir o tempo é simplesmente "Get-Date". Você não tem esse problema com o encaminhamento de saída e assim por diante.
$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start
Resultado:
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
Este é um one-liner que evita a expansão atrasada , o que pode perturbar certos comandos:
cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "
A saída é algo como:
14:30:27.58$ ... 14:32:43.17$ rem/
Para longo prazo testes substituir $T
por $D, $T
e %TIME%
por %DATE%, %TIME%
incluir a data.
Para usar isso dentro de um arquivo em lotes , substitua %Z
por %%Z
.
Aqui está um one-liner aprimorado (sem expansão tardia também):
cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"
A saída é semelhante a esta:
2015/09/01, 14:30:27.58$ rem/ ... 2015/09/01, 14:32:43.17$ prompt
Essa abordagem não inclui o processo de instanciar uma nova cmd
no resultado, nem o prompt
(s) comando (s).
Dependendo da versão do Windows que você está usando, apenas a execução bash
o colocará no modo Bash. Isso permitirá que você use vários comandos que não estão disponíveis diretamente no PowerShell (como o time
comando). Cronometrar seu comando agora é tão fácil quanto executar:
# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>
Nota: Você pode sair facilmente do modo Bash e retornar ao seu shell principal executando
exit
enquanto estiver no modo Bash.
Isso funcionou perfeitamente para mim (Windows 10) depois de experimentar outros métodos (como Measure-Command
) que às vezes produzem estatísticas indesejadas. Espero que isso funcione para você também.
Caso alguém mais tenha procurado uma resposta para essa pergunta, existe uma função da API do Windows chamada GetProcessTimes()
. Não parece muito trabalho escrever um pequeno programa C que inicie o comando, faça essa chamada e retorne os tempos do processo.
Este é um comentário / edição para agradável de Luke Sampson timecmd.bat
e resposta para
Por alguma razão, isso só me dá saída em segundos inteiros ... o que para mim é inútil. Quero dizer que executo a pausa do timecmd, e isso sempre resulta em 1,00 s, 2,00 s, 4,00 s ... até 0,00 s! Windows 7. - Camilo Martin, 25 de setembro de 2013 às 16:00 "
Em algumas configurações, os delimitadores podem diferir. A seguinte mudança deve abranger os países da maioria dos países ocidentais.
set options="tokens=1-4 delims=:,." (added comma)
Os %time%
milissegundos funcionam no meu sistema depois de adicionar ','
(* porque o site não permite nenhum comentário e não mantém um bom controle de identidade, embora eu sempre use o mesmo email de convidado que combinado com o ipv6 ip e a impressão digital do navegador seja suficiente para identificar exclusivamente sem senha)
Aqui está o meu método, sem conversão e sem ms. É útil determinar as durações de codificação (embora limitadas 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.
O script a seguir usa apenas "cmd.exe" e gera o número de milissegundos desde o momento em que um pipeline é criado até o momento em que o processo anterior ao script termina. ou seja, digite seu comando e direcione para o script. Exemplo: "timeout 3 | runtime.cmd" deve render algo como "2990". Se você precisar da saída do tempo de execução e da saída stdin, redirecione o stdin antes do pipe - ex: "dir / s 1> temp.txt | runtime.cmd" despejaria a saída do comando "dir" para "temp.txt" e imprimiria o tempo de execução no console.
:: --- 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
A resposta de driblio pode ser um pouco mais curta (embora não seja muito legível)
@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 a observação de Luke Sampson, esta versão é octal segura, embora a tarefa deva ser concluída em 24 horas.
set _time=%time: =0%
corrige o problema da hora de um dígito - substitua nos dois lugares.
No diretório em que está o seu programa, digite notepad mytimer.bat
, clique em 'yes' para criar um novo arquivo.
Cole o código abaixo, substituindo YourApp.exe
pelo seu programa, e salve.
@echo off
date /t
time /t
YourApp.exe
date /t
time /t
Digite mytimer.bat
na linha de comando e pressione Enter.
meu código fornece o tempo de execução em milissegundos, até 24 horas, é insensível à localidade e responde por valores negativos se o código for executado até meia-noite. ele usa expansão atrasada e deve ser salvo em um arquivo cmd / bat.
antes do seu 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%
após o seu 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
se você deseja tempo de execução no formato HH: mm: ss.000, adicione:
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
variável t2
mantém seu tempo de execução, você pode echo %t2%
exibi-lo.
Tendo o Perl instalado a solução de contratações disponível, execute:
C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result
STDERR vem antes dos 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 um sub para retornar o tempo em centésimos 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" com formato Regional, 24h e suporte a entrada mista
Adaptando o corpo do método de substituição de Aacini , sem IFs, apenas um FOR (minha correção regional)
1: Arquivo timer.bat colocado em algum lugar no% PATH% ou no diretório atual
@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:
temporizador & echo start_cmds & tempo limite / t 3 & echo end_cmds & temporizador
temporizador e temporizador "23: 23: 23,00"
temporizador "23: 23: 23,00" & temporizador
temporizador "13.23.23,00" e temporizador "03: 03: 03.00"
timer e timer "0: 00: 00.00" no & cmd / v: on / c eco até meia-noite =! Timer_end!
A entrada agora pode ser mista, para aqueles improváveis, mas possíveis alterações no formato de hora durante a execução
2: Função : timer incluído no script em lote (uso de exemplo abaixo):
@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 testá-lo, copie e cole as seções de código acima e abaixo
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 e CS, DS representam final de dois pontos, final de ponto e conjunto de dois pontos, conjunto de pontos - usado para suporte a formatos mistos
O script a seguir emula o tempo da época * nix, mas é local e regional. Ele deve lidar com casos de borda de calendário, incluindo anos bissextos. Se o Cygwin estiver disponível, os valores da época poderão ser comparados especificando a opção Cygwin .
Estou no EST e a diferença relatada é de 4 horas, o que é relativamente correto. Existem algumas soluções interessantes para remover as dependências regionais e TZ, mas nada trivial que eu notei.
@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');"
não há necessidade de cygwin ou utilitários não confiáveis. Útil quando o PHP está disponível localmente
precisão e formato de saída podem ser facilmente ajustados
a mesma ideia pode ser portada para o PowerShell