22

Can someone point me to a way of adding a timer to a Windows batch file? I need to track the time my batch runs from start.

2
  • what version of DOS are you using? Commented Nov 30, 2010 at 12:48
  • im using version 5.2.379 Commented Nov 30, 2010 at 13:25

7 Answers 7

20

Refactored the code to calculate the elapsed time:

  • less code in calculation,
  • provided padding for elapsed time less than .1 seconds,
  • using labels to allow calling it multiple times, and to group the timer code.

Reusable code:

:StartTimer
:: Store start time
set StartTIME=%TIME%
for /f "usebackq tokens=1-4 delims=:., " %%f in (`echo %StartTIME: =0%`) do set /a Start100S=1%%f*360000+1%%g*6000+1%%h*100+1%%i-36610100
goto :EOF

:StopTimer
:: Get the end time
set StopTIME=%TIME%
for /f "usebackq tokens=1-4 delims=:., " %%f in (`echo %StopTIME: =0%`) do set /a Stop100S=1%%f*360000+1%%g*6000+1%%h*100+1%%i-36610100
:: Test midnight rollover. If so, add 1 day=8640000 1/100ths secs
if %Stop100S% LSS %Start100S% set /a Stop100S+=8640000
set /a TookTime=%Stop100S%-%Start100S%
set TookTimePadded=0%TookTime%
goto :EOF

:DisplayTimerResult
:: Show timer start/stop/delta
echo Started: %StartTime%
echo Stopped: %StopTime%
echo Elapsed: %TookTime:~0,-2%.%TookTimePadded:~-2% seconds
goto :EOF

Calling code:

call :StartTimer
:: 
:: Add your script functionality here
::
call :StopTimer
call :DisplayTimerResult
pause

call :StartTimer
:: 
:: Add more script functionality here
::
call :StopTimer
call :DisplayTimerResult
goto :EOF

Note the "1"-prefix to avoid interpretation errors of zero-padded values as octal values (08 and 09), and the correction with the appropriate constant. As this might be confusing to understand the core calculation, an alternative to the one-line for statement would be something like the following:

for /f "usebackq tokens=1-4 delims=:., " %%f in (`echo.%StartTIME%`) do set TempTIME=%%f %%g %%h %%i
for /f "usebackq tokens=1-4" %%f in (`echo %TempTIME: 0= %`) do set /a Start100S=%%f*360000+%%g*6000+%%h*100+%%i
Sign up to request clarification or add additional context in comments.

Comments

11

A minimalistic version with elapsed time in seconds.

@set /A _tic=%time:~0,2%*3600^
            +%time:~3,1%*10*60^
            +%time:~4,1%*60^
            +%time:~6,1%*10^
            +%time:~7,1% >nul

:: actual script

@set /A _toc=%time:~0,2%*3600^
            +%time:~3,1%*10*60^
            +%time:~4,1%*60^
            +%time:~6,1%*10^
            +%time:~7,1% >nul

@set /A _elapsed=%_toc%-%_tic
@echo %_elapsed% seconds.

2 Comments

but I have an hour and a half script. how would it be done for minutes instead of seconds? sorry if for you seems too simple!
Thanks @migonzalvar, this was just what I needed. For the curious, you can't retrieve two digits at a time for minutes and seconds because a leading 0 will cause the number to be interpreted as octal. It works for hours because there is a leading space, not a 0. And you do need the space before the ">nul" because (for example) "2>nul" means redirect stderr. (Oh, and those trailing ^ symbols escape the newline.)
3

As far as I know there is no explicit 'timer' command you can use in batch files - however there is a fairly simple solution. At the top of your batch file record the current time (start time) at the end of the batch file record the current time (end time) and then compare the two. Something like this should do it (it does seem overly complicated but it handles most quirks of time):

:: Store start time
set StartTIME=%TIME%
set H=%StartTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StartTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StartTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StartTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)
set /a Start100S=%H%*360000+%M%*6000+%S%*100+%U%

:: 
:: Add your script functionality here
::

:: Get the end time
set StopTIME=%TIME%
set H=%StopTIME:~0,2%
if "%H:~0,1%"==" " set H=%H:~1,1%
if "%H:~0,1%"=="0" set H=%H:~1,1%
set M=%StopTIME:~3,2%
if "%M:~0,1%"=="0" set M=%M:~1,1%
set S=%StopTIME:~6,2%
if "%S:~0,1%"=="0" set S=%S:~1,1%
set U=%StopTIME:~9,2%
if "%U:~0,1%"=="0" set U=%U:~1,1%
)

set /a Stop100S=%H%*360000+%M%*6000+%S%*100+%U%

:: Test midnight rollover. If so, add 1 day=8640000 1/100ths secs
if %Stop100S% LSS %Start100S% set /a Stop100S+=8640000
set /a TookTime=%Stop100S%-%Start100S%

echo Started: %StartTime%
echo Stopped: %StopTime%
echo Elapsed: %TookTime:~0,-2%.%TookTime:~-2% seconds

Alternatively #1 : The Windows Server 2k3 resource kit includes timeit.exe. You can use this to display various performance stats for your script.

Alternatively #2 : You could go much simpler than the script posted above and do this:

echo %time% 
::
:: Your script functionality
::
echo %time%

However, this won't give you execution time in seconds.

Comments

2

Structure your program like this:

@echo off
setlocal enabledelyedexpansion

set T[1]=%time%

 ::
 :: Your program goes here...
 :: 

set T[2]=%time%
call TIMER

Here is the code for the TIMER.BAT program. Save it as a seperate file somewhere in your path.

for /l %%t in (1,1,2) do for /f "tokens=1-4 delims=:." %%a in ("!T[%%t]!") do (
 set "T[%%t]=!T[%%t]: =0!"
 set "h[%%t]=%%a" & if "!h[%%t]:~0,1!"=="0" set "h[%%t]=!h[%%t]:~1!"
 set "m[%%t]=%%b" & if "!m[%%t]:~0,1!"=="0" set "m[%%t]=!m[%%t]:~1!"
 set "s[%%t]=%%c" & if "!s[%%t]:~0,1!"=="0" set "s[%%t]=!s[%%t]:~1!"
 set "c[%%t]=%%d" & if "!c[%%t]:~0,1!"=="0" set "c[%%t]=!c[%%t]:~1!"
 set /a T[%%t]=!h[%%t]!*360000+!m[%%t]!*6000+!s[%%t]!*100+!c[%%t]!
)

set /a c=!T[2]!-!T[1]!
set /a h=!c!/360000 & set /a c%%=360000 & if !h! lss 10 set "h= !h!"
set /a m=!c!/6000   & set /a c%%=6000   & if !m! lss 10 set "m=0!m!"
set /a s=!c!/100    & set /a c%%=100    & if !s! lss 10 set "s=0!s!"
echo !h!:!m!:!s!.!c!

Comments

2

This timer is pretty accurate, and counts down from 5. I'm not sure how you could add this into your code though. Note:This is a very basic batch timer, and the other answers are probably better, but this is just a quick way to design your own batch timer with simple code.

@echo off
cls
set /a time=5
:hi
cls
echo Time:%time%
ping localhost -n 2 >nul
set /a time=%time%-1
if %time%==0 (
goto timeup
)else goto :hi
:timeup
cls
echo Time is up!
pause

Also to change the time this timer starts at, just change set /a time=5 to set /a time=(whatever time you want to start at)

Comments

1

You can try this one(Shorter..)

@echo off
:loop
set TA=%time% & echo %time%--A

echo Put Your Code Here...

set TB=%time% & echo %time%--B

call:Timediff %TA% %TB% Tab
for /f "tokens=1-3 delims=:" %%a in ("%TAB%")do echo Time difference: %%a hours %%b minutes and %%c seconds
pause
goto:loop

:: /* ---------- Timediff ---------------
:Timediff [%t1%] [%t2%] [par|0]
for %%a in (+%1 +%2 +%3)do if "%%a"=="+" echo No Parameters!!&exit/b
setlocal enabledelayedexpansion
:timediff_1
set P2=%~1&set "P2=!P2::=!"
set/a P2=%P2:.=%-4000*(%P2:~,4%+60*%P2:~,2%)
if not "%3"=="" set P1=!P2!&shift&goto:timediff_1
if !P2! geq !P1! (set/a df=!P2!-!P1!) else set/a df=!P2!-!P1!+8640000
set/a h=df/360000,m=df%%360000/6000,s=df%%6000/100,pt=df%%100
if %pt% leq 9 set pt=0%pt%
endlocal&if %2.==0. (echo\%h%:%m%:%s%.%pt%) else set %2=%h%:%m%:%s%.%pt%&goto:eof
:: ------------- Timediff ------------- */

Comments

0

I think the best option will be to use powershell as

@echo off
for /f %%t in ('powershell "(get-date).tofiletime()"') do set mst=%%t

rem some commands

powershell ((get-date).tofiletime() - %mst%)

this will print the time passed in milliseconds

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.