@setlocal @echo off set begintime=%time% @echo ----------------------------------------- @echo Starting: %begintime% ... set /p var=Tell me something and hit [return] ^> @echo ----------------------------------------- set finishtime=%time% call :timediff %begintime% %finishtime% ::@echo. @echo Done at %finishtime%, it took you %timetaken% sec to tell me [%var%]. @echo ----------------------------------------- goto eos :: :timediff :: echo %1, %2 set starttime=%1 set endtime=%2 if [%starttime:~1,1%] == [:] set starttime=0%starttime% if [%endtime:~1,1%] == [:] set endtime=0%endtime% 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%) :: 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% goto eos :: End Of Script :eos @endlocalNotice the code under the timediff label, this is where the skill is. It takes the time before and the time after as parameters, and computes the value of a timetaken variable that you can display.
It is all based on the value of the %time% variable:
Prompt> echo %time% 10:44:29.25and also on the substring manipulation, performed with the ":~" characters.
It will generate an output like this one:
----------------------------------------- Starting: 10:40:02.63 ... Tell me something and hit [return] > Whatever ----------------------------------------- Done at 10:40:11.17, it took you 8.54 sec to tell me [Whatever]. -----------------------------------------There is a gotcha, though. A problem remains, when you write something like this:
set /a num=(010 + 010)Windows comes up with
16It is because it considers that 010 is in octal, as such, understood as 8 (decimal). Whatever begins with a '0' is an octal digit, so '08', '09', etc, are invalid numbers.
In the calculation above, you need to remove the leading '0' for the computation to be done in decimal...
Being aware of this, the script becomes (its timediff part, and on):
:timediff :: echo from [%1] to [%2] set starttime=%1 set endtime=%2 if [%starttime:~1,1%] == [:] set starttime=0%starttime% if [%endtime:~1,1%] == [:] set endtime=0%endtime% set startcsec=%starttime:~9,2% set startsecs=%starttime:~6,2% set startmins=%starttime:~3,2% set starthour=%starttime:~0,2% :: Remove leading 0 (considered as octal numbers) call :removeLeadingZero %startcsec% set startcsec=%truncated% call :removeLeadingZero %startsecs% set startsecs=%truncated% call :removeLeadingZero %startmins% set startmins=%truncated% call :removeLeadingZero %starthour% set starthour=%truncated% :: set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%) :: set endcsec=%endtime:~9,2% set endsecs=%endtime:~6,2% set endmins=%endtime:~3,2% set endhour=%endtime:~0,2% :: Remove leading 0 (considered as octal numbers) call :removeLeadingZero %endcsec% set endcsec=%truncated% call :removeLeadingZero %endsecs% set endsecs=%truncated% call :removeLeadingZero %endmins% set endmins=%truncated% call :removeLeadingZero %endhour% set endhour=%truncated% :: 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% goto eos :: :removeLeadingZero set truncated=%1 :top if not [%truncated:~1%] == [] ( if [%truncated:~0,1%] == [0] ( set truncated=%truncated:~1% goto top ) ) :: if not [%1] == [%truncated%] @echo [%1] becomes [%truncated%] goto eos :: End Of Script :eos @endlocalNotice the new sub-routine removeLeadingZero. It leaves at least one character in the string to truncate ('0' is the same in octal and decimal). The statement if not [%truncated:~1%] == [] (... means "if the length of %truncated% is greater than 1". The statement
if [%starttime:~1,1%] == [:] set starttime=0%starttime%is here to manage the times before 10:00. It's returned like
9:55:10.34That makes the first ':' in position 2, instead of 3, as expected. This last line in transformed so it's saying
09:55:10.34This way, all is good!
Now, if you don't want to copy-paste this code every time you want to time a command, start the script this way:
@setlocal @echo off set begintime=%time% @echo ----------------------------------------- @echo Starting: %begintime% ... @echo ----------------------------------------- :: Execution to time goes here %* :: @echo ----------------------------------------- set finishtime=%time% call :timediff %begintime% %finishtime% ::@echo. @echo Done at %finishtime%, execution of [%*] took %timetaken% sec. @echo ----------------------------------------- goto eos :: :timediff :: echo from [%1] to [%2] ...Name it something like "elapsed.cmd", and run it this way:
Prompt> elapsed java -version ----------------------------------------- Starting: 9:24:08.48 ... ----------------------------------------- java version "1.6.0_20" Java(TM) SE Runtime Environment (build 1.6.0_20-b02) Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode) ----------------------------------------- Done at 9:24:08.63, execution of [java -version] took 0.15 sec. -----------------------------------------And that's it. The full script is 74 lines long, including comments. Here is the full script:
@setlocal @echo off @echo Usage: @echo %0 ^<command ^<prm1 ^<prm2 ^<...^>^>^> set begintime=%time% @echo ----------------------------------------- @echo Starting: %begintime% ... @echo ----------------------------------------- @echo %CD%^> %* :: Execution to time goes here %* :: @echo ----------------------------------------- set finishtime=%time% call :timediff %begintime% %finishtime% ::@echo. @echo Done at %finishtime%, execution of [%*] took %timetaken% sec. @echo ----------------------------------------- goto eos :: :timediff :: echo from [%1] to [%2] set starttime=%1 set endtime=%2 if [%starttime:~1,1%] == [:] set starttime=0%starttime% if [%endtime:~1,1%] == [:] set endtime=0%endtime% set startcsec=%starttime:~9,2% set startsecs=%starttime:~6,2% set startmins=%starttime:~3,2% set starthour=%starttime:~0,2% :: Remove leading 0 (considered as octal numbers) call :removeLeadingZero %startcsec% set startcsec=%truncated% call :removeLeadingZero %startsecs% set startsecs=%truncated% call :removeLeadingZero %startmins% set startmins=%truncated% call :removeLeadingZero %starthour% set starthour=%truncated% :: set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%) :: set endcsec=%endtime:~9,2% set endsecs=%endtime:~6,2% set endmins=%endtime:~3,2% set endhour=%endtime:~0,2% :: Remove leading 0 (considered as octal numbers) call :removeLeadingZero %endcsec% set endcsec=%truncated% call :removeLeadingZero %endsecs% set endsecs=%truncated% call :removeLeadingZero %endmins% set endmins=%truncated% call :removeLeadingZero %endhour% set endhour=%truncated% :: 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% goto eos :: :removeLeadingZero set truncated=%1 :top if not [%truncated:~1%] == [] ( if [%truncated:~0,1%] == [0] ( set truncated=%truncated:~1% goto top ) ) :: if not [%1] == [%truncated%] @echo [%1] becomes [%truncated%] goto eos :: End Of Script :eos @endlocal