Esiste un modo integrato per misurare i tempi di esecuzione di un comando sulla riga di comando di Windows?
Esiste un modo integrato per misurare i tempi di esecuzione di un comando sulla riga di comando di Windows?
Risposte:
Se si utilizza Windows 2003 (si noti che Windows Server 2008 e versioni successive non sono supportate) è possibile utilizzare il Resource Kit di Windows Server 2003, che contiene timeit.exe che visualizza statistiche dettagliate sull'esecuzione. Ecco un esempio, temporizzando il 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
È possibile ottenere TimeIt nel Resource Kit di Windows 2003. Scaricalo qui .
In alternativa, Windows PowerShell ha un comando integrato simile al comando "time" di Bash. Si chiama "Misura-comando". Dovrai assicurarti che PowerShell sia installato sul computer che lo esegue.
Esempio di input:
Measure-Command {echo hi}
Esempio di output:
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
nella directory corrente, utilizzare questo: Measure-Command { .\your.exe }
. Apparentemente PowerShell non esegue le cose pwd
se non esplicitamente detto.
<stdout>
risultati del comando racchiuso tra parentesi graffe!
Se vuoi
Prova a copiare il seguente script in un nuovo file batch (ad esempio 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 inserisci timecmd.bat in una directory nel tuo percorso, puoi chiamarlo da qualsiasi luogo come questo:
timecmd [your command]
Per esempio
C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18
Se si desidera eseguire il reindirizzamento dell'output, è possibile citare il comando in questo modo:
timecmd "dir c:\windows /s > nul"
Questo dovrebbe gestire i comandi che vengono eseguiti da prima a dopo mezzanotte, ma l'output sarà errato se il comando viene eseguito per 24 ore o più.
timecmd pause
, corro , e risulta sempre in 1,00 secondi, 2,00 secondi, 4,00 secondi ... anche 0,00 secondi! Windows 7.
delims=:.
in delims=:.,
, e quindi dovrebbe funzionare "su tutta la linea".
set start=10:10:10.10
set end=10:11:10.09
E command took 0:1:-1.99 (59.99s total)
genererà : Dovresti invertire l'ordine delle 4 righe che fanno confronti "lss 0", in modo che il carry proceda correttamente da cifre sessagesimali basse a alte. Quindi l'output diventa: command took 0:0:59.99 (59.99s total)
Hehe, la soluzione più semplice potrebbe essere questa:
echo %time%
YourApp.exe
echo %time%
Funziona su ogni Windows pronto all'uso.
Nel caso in cui un'applicazione utilizzi l'output della console, potrebbe essere utile memorizzare l'ora di inizio in una variabile temporanea:
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%
(Spiacenti, non è possibile ottenere nuove righe nel commento)
set
per fare i conti . ;-)
Oh aspetta, non importa, l'hai già fatto di seguito.
Solo una piccola espansione della risposta di Casey.K sull'uso di Measure-Command
da PowerShell :
È possibile richiamare PowerShell dal prompt dei comandi standard, in questo modo:
powershell -Command "Measure-Command {echo hi}"
Questo manterrà l'output standard, ma puoi impedirlo aggiungendo | Out-Default
così da PowerShell:
Measure-Command {echo hi | Out-Default}
O da un prompt dei comandi:
powershell -Command "Measure-Command {echo hi | Out-Default}"
Ovviamente, sei libero di racchiuderlo in un file di script *.ps1
o *.bat
.
measureTime.bat "c:\program files\some dir\program.exe"
Il one-liner che uso in Windows Server 2008 R2 è:
cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"
Finché mycommand non richiede virgolette (che si avvita con l'elaborazione delle virgolette di cmd). Lo scopo /v:on
è consentire la valutazione indipendente dei due diversi valori TIME anziché una volta all'esecuzione del comando.
^
in cmd (come ^"
)
cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
.
echo %time% & *mycommand* & call echo %^time%
. Vedi anche questa risposta .
cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
Se hai una finestra di comando aperta e chiama i comandi manualmente, puoi visualizzare un timestamp su ogni prompt, ad es
prompt $d $t $_$P$G
Ti dà qualcosa del tipo:
23.03.2009 15:45:50,77
C:\>
Se si dispone di uno script batch di piccole dimensioni che esegue i comandi, disporre di una riga vuota prima di ciascun comando, ad es
(riga vuota)
myCommand.exe
(prossima riga vuota)
myCommand2.exe
È possibile calcolare il tempo di esecuzione per ciascun comando dalle informazioni sull'ora nel prompt. Il migliore sarebbe probabilmente convogliare l'output in un file di testo per ulteriori analisi:
MyBatchFile.bat > output.txt
Dato che altri stanno raccomandando di installare cose come freeware e PowerShell, potresti anche installare Cygwin , che ti darebbe accesso a molti comandi Unix di base come il tempo :
abe@abe-PC:~$ time sleep 5
real 0m5.012s
user 0m0.000s
sys 0m0.000s
Non sono sicuro di quanto sovraccarico Cygwin aggiunge.
Non abbastanza elegante come alcune delle funzionalità su Unix, ma crea un file cmd che assomigli a:
@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T
Ciò visualizzerà i tempi di inizio e fine in questo modo:
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
ha /t
un'opzione che mostra solo l'ora di sistema corrente, senza che ti venga richiesto di inserire una nuova ora. Tuttavia, quando lo fai visualizza solo ore e minuti, che potrebbero non essere abbastanza buoni per alcuni usi. (Vedi la risposta di John Snow a questa domanda.)
time /T
è utilizzabile solo se il processo dura diversi minuti! time < nul
è più brutto ma più preciso.
echo %time%
che fornisce lo stesso formato e precisione di time < nul
, ma eviti l' Enter the new time:
output ...
wmic os get LocalDateTime
Uso un software gratuito chiamato "GS Timer".
Basta creare un file batch come questo:
timer
yourapp.exe
timer /s
Se hai bisogno di una serie di orari, inserisci semplicemente l'output del timer / s in un file .txt.
Puoi scaricarlo qui: Utilità DOS gratuite di Gammadyne
La risoluzione è di 0,1 secondi.
Sto usando Windows XP e per qualche motivo timeit.exe non funziona per me. Ho trovato un'altra alternativa: PTIME. Funziona molto bene
http://www.pc-tools.net/win32/ptime/
Esempio -
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
C'è anche TimeMem (marzo 2012):
Questa è un'utilità di Windows che esegue un programma e visualizza i suoi tempi di esecuzione, l'utilizzo della memoria e le statistiche IO. È simile nella funzionalità all'utilità di tempo Unix.
Finché non dura più di 24 ore ...
@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.
Ecco un
Esempio di utilizzo:
timeout 1 | TimeIt.cmd
Execution took ~969 milliseconds.
Copia e incolla questo in un editor come ad esempio Notepad ++ e salvalo come 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
^ - Basato sulla versione di "Daniel Sparks"
Un'alternativa al tempo di misura è semplicemente "Get-Date". Non hai quella seccatura con l'output di inoltro e così via.
$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start
Produzione:
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
Questo è un one-liner che evita l'espansione ritardata , che potrebbe disturbare alcuni comandi:
cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "
L'output è simile a:
14:30:27.58$ ... 14:32:43.17$ rem/
Per lungo termine prove di sostituire $T
da $D, $T
e %TIME%
per %DATE%, %TIME%
includere la data.
Per usarlo all'interno di un file batch , sostituiscilo %Z
con %%Z
.
Ecco un one-liner migliorato (anche senza espansione ritardata ):
cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"
L'output è simile al seguente:
2015/09/01, 14:30:27.58$ rem/ ... 2015/09/01, 14:32:43.17$ prompt
Questo approccio non include il processo di istituzione di un nuovo cmd
nel risultato, né include i prompt
comandi.
A seconda della versione di Windows che stai utilizzando, solo l'esecuzione bash
ti porterà in modalità Bash. Ciò consentirà di utilizzare un gruppo di comandi che non sono disponibili direttamente su PowerShell (come il time
comando). Il cronometraggio del comando è ora semplice come l'esecuzione:
# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>
Nota: è possibile uscire facilmente dalla modalità Bash e tornare alla shell principale eseguendo
exit
in modalità Bash.
Questo ha funzionato perfettamente per me (Windows 10) dopo aver provato altri metodi (come Measure-Command
) che a volte producono statistiche indesiderate. Spero che questo funzioni anche per te.
Nel caso in cui qualcun altro sia venuto qui alla ricerca di una risposta a questa domanda, c'è una funzione API di Windows chiamata GetProcessTimes()
. Non sembra troppo lavoro per scrivere un piccolo programma C che avvierebbe il comando, effettuasse questa chiamata e restituisse i tempi di processo.
Questo è un commento / modifica per il simpatico timecmd.bat
e la risposta di Luke Sampson
Per qualche ragione, questo mi dà output in pochi secondi ... il che per me è inutile. Voglio dire che eseguo pausa timecmd, e risulta sempre in 1,00 secondi, 2,00 secondi, 4,00 secondi ... anche 0,00 secondi! Windows 7. - Camilo Martin, 25 settembre 13 alle 16:00 "
In alcune configurazioni i delimitatori possono differire. La seguente modifica dovrebbe riguardare almeno la maggior parte dei paesi occidentali.
set options="tokens=1-4 delims=:,." (added comma)
Il %time%
millisecondi funzionano sul mio sistema dopo aver aggiunto ','
(* perché il sito non consente commenti anonimi e non tiene traccia dell'identità, anche se utilizzo sempre la stessa e-mail ospite che, combinata con ipv6 ip e impronta digitale del browser, dovrebbe essere sufficiente per identificare in modo univoco senza password)
Ecco il mio metodo, nessuna conversione e nessun ms. È utile determinare la durata della codifica (limitata a 24 ore):
@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.
Lo script seguente utilizza solo "cmd.exe" e genera il numero di millisecondi dal momento in cui viene creata una pipeline al momento in cui termina il processo che precede lo script. ad esempio, digitare il comando e reindirizzare allo script. Esempio: "timeout 3 | runtime.cmd" dovrebbe produrre qualcosa come "2990." Se hai bisogno sia dell'output di runtime sia dell'output stdin, reindirizza stdin prima del pipe - es: "dir / s 1> temp.txt | runtime.cmd" scarica l'output del comando "dir" su "temp.txt" e stamperebbe il runtime sulla 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
La risposta di driblio può essere resa un po 'più breve (anche se non molto leggibile)
@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
Per l' osservazione di Luke Sampson questa versione è assolutamente sicura, sebbene l'attività dovrebbe essere completata in 24 ore.
set _time=%time: =0%
risolve il problema relativo all'ora a una cifra: sostituire in entrambi i punti.
Nella directory in cui si trova il programma, digitare notepad mytimer.bat
, fare clic su "Sì" per creare un nuovo file.
Incolla il codice qui sotto, sostituendolo YourApp.exe
con il tuo programma, quindi salva.
@echo off
date /t
time /t
YourApp.exe
date /t
time /t
Digita mytimer.bat
la riga di comando, quindi premi Invio.
il mio codice ti dà il tempo di esecuzione in millisecondi, fino a 24 ore, non è sensibile alle impostazioni locali e tiene conto dei valori negativi se il codice scorre per mezzanotte. usa l'espansione ritardata e dovrebbe essere salvata in un file cmd / bat.
prima del tuo codice:
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%
dopo il tuo codice:
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 vuoi un tempo di esecuzione in formato HH: mm: ss.000, aggiungi:
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
La variabile t2
mantiene il tempo di esecuzione, è possibile echo %t2%
visualizzarlo.
Dopo aver installato Perl la soluzione di assunzioni disponibile, eseguire:
C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result
STDERR viene prima dei secondi misurati
#!/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;
Utilizzo di un sub per restituire il tempo in centesimi di secondo
::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 regionale, 24 ore e supporto input misto
Adattamento di Aacini corpo del metodo di sostituzione , nessun IF, solo un FOR (la mia correzione regionale)
1: File timer.bat posizionato da qualche parte in% PATH% o nella directory corrente
@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
Utilizzo:
timer & echo start_cmds e timeout / t 3 e echo end_cmds e timer
timer e timer "23: 23: 23,00"
timer "23: 23: 23,00" & timer
timer "13.23.23,00" & timer "03: 03: 03.00"
timer & timer "0: 00: 00.00" no & cmd / v: on / c echo fino a mezzanotte =! Timer_end!
L'input ora può essere miscelato, per quelli improbabili, ma possibili cambi di formato dell'ora durante l'esecuzione
2: Funzione : timer in bundle con lo script batch (utilizzo di esempio di seguito):
@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
:: per testarlo, copia e incolla le sezioni di codice sopra e sotto
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, supporto DS per estremità dei due punti, estremità dei punti e due punti, set di punti - utilizzato per il supporto di formati misti
Il seguente script emula il tempo di epoca * nix, ma è locale e regionale. Dovrebbe gestire i casi del bordo del calendario compreso gli anni bisestili. Se Cygwin è disponibile, i valori di epoca possono essere confrontati specificando l' opzione Cygwin .
Sono in EST e la differenza segnalata è di 4 ore, il che è relativamente corretto. Ci sono alcune soluzioni interessanti per rimuovere la TZ e le dipendenze regionali, ma nulla di banale che ho notato.
@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');"
nessuna necessità di cygwin o utility non attendibili. Utile quando PHP è disponibile localmente
la precisione e il formato di output possono essere facilmente modificati
la stessa idea può essere trasferita per PowerShell