Computer Hope

Microsoft => Microsoft DOS => Topic started by: Frank on August 11, 2008, 03:27:05 AM

Title: Calculating using time
Post by: Frank on August 11, 2008, 03:27:05 AM
I also have a calculating problem.
I would like to calculate how long some commands take.
For example:

@echo off
set old=%time%
echo %old%
rem some commands here
echo %old% %time%
set /A delay="%time% - %old%"
echo %delay%
pause

I get an error "Missing operator" with an 18 on the following line.
If I remove the % signs I don't get an error just "-19" on the following line. There must be some sort of a syntax error, but I don't know enough about the set command it to rectify it. It would be nice if I understood the help file (set /?).
Any help would be appreciated.
Frank
Title: Re: Calculating using time
Post by: Dias de verano on August 11, 2008, 03:42:58 AM
what does %time% look like?
Title: Re: Calculating using time
Post by: Frank on August 11, 2008, 03:45:58 AM
%time% looks like 19:44:16.85
Frank
Title: Re: Calculating using time
Post by: Dias de verano on August 11, 2008, 04:25:53 AM
You have to remove the colons, separate out the hours, minutes and seconds, multiply hours x 3600, minutes x 60, and add to seconds to get seconds since midnight, then you can subtract one from another.
Title: Re: Calculating using time
Post by: Frank on August 11, 2008, 04:28:55 AM
o/k, this no longer sounds like a job for a batch file.
Frank
Title: Re: Calculating using time
Post by: Dias de verano on August 11, 2008, 04:34:54 AM
can be done, I've done it, when I get home in about 6 hrs I'll post it. The big trouble comes when you span midnight. You can get the PC's up time from Windows and use that. Catch me later.
Title: Re: Calculating using time
Post by: Frank on August 11, 2008, 04:38:39 AM
Thank you very much.
In 6.5 hours it will be 3:00am here so I will be asleep. But I'll look at the post when I get up.
Thanks again.
Frank
Title: Re: Calculating using time
Post by: Dias de verano on August 11, 2008, 11:07:55 AM
Have you got XP pro?

can you use the systeminfo command?

Title: Re: Calculating using time
Post by: Frank on August 11, 2008, 03:33:59 PM
Yes, I have Windows XP Pro SP2.
Title: Re: Calculating using time
Post by: Dias de verano on August 11, 2008, 03:45:03 PM
Number of seconds since computer was last booted:

for /f "tokens=1-14 delims= " %%A in ('systeminfo ^| find "System Up Time"') do set /a secs=86400*%%D+3600*%%F+60*%%H+%%J
Title: Re: Calculating using time
Post by: Frank on August 11, 2008, 11:27:54 PM
Thank you very much.
This is what I did:

@echo off
for /f "tokens=1-14 delims= " %%A in ('systeminfo ^| find "System Up Time"') do set /a secs1=86400*%%D+3600*%%F+60*%%H+%%J
rem some commands to do
for /f "tokens=1-14 delims= " %%A in ('systeminfo ^| find "System Up Time"') do set /a secs2=86400*%%D+3600*%%F+60*%%H+%%J
set /a secs3=secs2-secs1
echo %secs3% seconds taken.
pause

I am not sure I understand the syntax, expecially %%H etc. but it works that's the main thing.
Thanks
Title: Re: Calculating using time
Post by: Dias de verano on August 12, 2008, 01:57:00 AM
regarding the syntax - the output of systeminfo is a long string of words separated by spaces, so %%B to %% J are "implicit variables" created by the tokens=1-14 section. Actually, 1-11 would do just as well.

You should note that the actual systeminfo operation takes about 2 seconds, (on my system) so you should subtract that from the second time. You can establish the size of this delay overhead by running the code like this


Code: [Select]
@echo off
for /f "tokens=1-14 delims= " %%A in ('systeminfo ^| find "System Up Time"') do set /a secs1=86400*%%D+3600*%%F+60*%%H+%%J

rem nothing here

for /f "tokens=1-14 delims= " %%A in ('systeminfo ^| find "System Up Time"') do set /a secs2=86400*%%D+3600*%%F+60*%%H+%%J
set /a secs3=secs2-secs1
echo %secs3% seconds taken.
pause
Title: Re: Calculating using time
Post by: Frank on August 12, 2008, 04:06:35 PM
Thanks,
Tried it and the overhead on my system is also 2 seconds.
Title: Re: Calculating using time
Post by: Dias de verano on August 13, 2008, 12:46:36 PM
If you do not mind that this will give wrong results if the first time is before midnight, and the second time is after (the next, or a subsequent!) midnight, then this code takes the hours, minutes, seconds, and hundredths of a second in the %time% variable and converts to a figure in milliseconds, and it takes much less than 2 seconds! I would not trust it to beyond around 50 msec though.

Code: [Select]
@echo off
set ntime=%time%

REM slice up %time%
REM presumes 24 hr clock hh:mm:ss.nn
REM nn=1/100ths of seconds
set hh=%ntime:~0,2%
set mm=%ntime:~3,2%
set ss=%ntime:~6,2%
set cs=%ntime:~9,2%

REM remove any leading zeroes because set /a
REM treats them as indicating octal values
REM and barfs at 08 and 09, understandably!
REM also remove leading space if hour < 10
if "%hh:~0,1%"==" " set hh=%hh:~1,1%
if "%mm:~0,1%"=="0" set mm=%mm:~1,1%
if "%ss:~0,1%"=="0" set ss=%ss:~1,1%
if "%cs:~0,1%"=="0" set cs=%cs:~1,1%

REM now they are all valid integer values, do the arithmetic
set /a msec=3600000*%hh%+60000*%mm%+1000*%ss%+10*%cs%
echo %msec%

say you called it mtime.bat and stored it somewhere on your PATH, you could use it like this

With just that "REM code to be timed" line I am mostly seeing values between 100 & 200 msec with a few as low as 70 or as high as 230.

Code: [Select]
@echo off
for /f %%T in ('mtime.bat') do set time1=%%T
REM code to be timed
for /f %%T in ('mtime.bat') do set time2=%%T
set /a elapsed=%time2%-%time1%
echo elapsed %elapsed% milliseconds
Title: Re: Calculating using time
Post by: Frank on August 14, 2008, 02:53:02 AM
That is cool.
Overhead on my computer is 110-140ms.
This is a much better solution that stepping through a file.
Thanks

Just thought, a dummy run could be made to determine the overhead and then subtract that amount at the end. This would be more acurate. The error that still exists is the variation between successive runs (+- 20ms).

Code: [Select]
@echo off
rem DO A DUMMY RUN TO FIND THE OVERHEAD
for /f %%T in ('mtime.bat') do set time1=%%T
for /f %%T in ('mtime.bat') do set time2=%%T
set /a overh=%time2%-%time1%

for /f %%T in ('mtime.bat') do set time1=%%T
REM code to be timed
for /f %%T in ('mtime.bat') do set time2=%%T
set /a elapsed=%time2%-%time1%-%overh%
echo elapsed %elapsed% milliseconds
pause
Title: Re: Calculating using time
Post by: Dias de verano on August 14, 2008, 10:11:45 AM
The error that still exists is the variation between successive runs (+- 20ms).

I did say, don't trust the system clock to provide more than around 100 msec accuracy
Title: Re: Calculating using time
Post by: Dias de verano on August 14, 2008, 11:40:30 AM
I have evolved a better method. Just read the clock at time1 and time 2 and do all the calculating at the end

1. elapsed-calc.bat

Code: [Select]
@echo off
set time1=%1
set time2=%2
set hh1=%time1:~0,2%
set mm1=%time1:~3,2%
set ss1=%time1:~6,2%
set cs1=%time1:~9,2%
if "%hh1:~0,1%"==" " set hh1=%hh1:~1,1%
if "%mm1:~0,1%"=="0" set mm1=%mm1:~1,1%
if "%ss1:~0,1%"=="0" set ss1=%ss1:~1,1%
if "%cs1:~0,1%"=="0" set cs1=%cs1:~1,1%
set hh2=%time2:~0,2%
set mm2=%time2:~3,2%
set ss2=%time2:~6,2%
set cs2=%time2:~9,2%
if "%hh2:~0,1%"==" " set hh2=%hh2:~1,1%
if "%mm2:~0,1%"=="0" set mm2=%mm2:~1,1%
if "%ss2:~0,1%"=="0" set ss2=%ss2:~1,1%
if "%cs2:~0,1%"=="0" set cs2=%cs2:~1,1%
set /a msec1=3600000*%hh1%+60000*%mm1%+1000*%ss1%+10*%cs1%
set /a msec2=3600000*%hh2%+60000*%mm2%+1000*%ss2%+10*%cs2%
set /a elapsed=%msec2%-%msec1%
echo %elapsed%

Use it like this

Code: [Select]
@echo off
set time1=%time%
rem code to be timed here
set time2=%time%
for /f %%A in ('elapsed-calc.bat %time1% %time2%') do set elapsed=%%A
echo elapsed time %elapsed% msec

With just that "rem code to be timed here" line I am getting 0 msec showing. Although the time value is shown in msec, obviously there is a 10 msec granularity since the clock only reads to hundredths of a second and in fact I have read that the system clock is not to be trusted to a greater accuracy than around 50 msec.

 



Title: Re: Calculating using time
Post by: Frank on August 14, 2008, 06:44:42 PM
Yes, much easier to implament.
I understand that the time resolution is 10ms. Therefore, no time measurement can be more accurate than within 10ms. But as you say, if the clock accuracy or repeatability is only within 50ms, then that is the most accurate this system can measure.

Since I am trying to measure between 2 and 10 seconds, an error of 50ms is of no consequence.
Thank a lot for these ideas.
Title: Re: Calculating using time
Post by: Dias de verano on August 16, 2008, 01:31:47 AM
Frank, I was up early this morning, and I discovered that my code is broken when the hour is less than 10. Although the system time string has a a leading space, this is stripped off when it is passed as a parameter to a batch file, unless:

1. You enclose it in quotes

2. You then dequote it in the batch file

See here

1. elapsed-calc.bat

Code: [Select]
@echo off

REM remove surrounding quotes (if any)
set time1=%~1
set time2=%~2
set hh1=%time1:~0,2%
set mm1=%time1:~3,2%
set ss1=%time1:~6,2%
set cs1=%time1:~9,2%
if "%hh1:~0,1%"==" " set hh1=%hh1:~1,1%
if "%mm1:~0,1%"=="0" set mm1=%mm1:~1,1%
if "%ss1:~0,1%"=="0" set ss1=%ss1:~1,1%
if "%cs1:~0,1%"=="0" set cs1=%cs1:~1,1%
set hh2=%time2:~0,2%
set mm2=%time2:~3,2%
set ss2=%time2:~6,2%
set cs2=%time2:~9,2%
if "%hh2:~0,1%"==" " set hh2=%hh2:~1,1%
if "%mm2:~0,1%"=="0" set mm2=%mm2:~1,1%
if "%ss2:~0,1%"=="0" set ss2=%ss2:~1,1%
if "%cs2:~0,1%"=="0" set cs2=%cs2:~1,1%
set /a msec1=3600000*%hh1%+60000*%mm1%+1000*%ss1%+10*%cs1%
set /a msec2=3600000*%hh2%+60000*%mm2%+1000*%ss2%+10*%cs2%
set /a elapsed=%msec2%-%msec1%
echo %elapsed%

2. Example of use in batch

Code: [Select]
@echo off
set time1=%time%
REM code to be timed here
set time2=%time%

REM surround time strings with quote marks
REM line edited to correct error found by Frank
for /f %%A in ('elapsed-calc.bat "%time1%" "%time2%"') do set elapsed=%%A
echo elapsed time %elapsed% msec

3. From the command line using command grouping (you did know about that?) to avoid typing delays when setting start & finish times

Code: [Select]
S:\Test>(
More? set tt1=
More? set tt2=
More? set tt1=%time%
More? wget -q http://www.programacion-tdt.com/Canal_24h.html
More? set tt2=%time%
More? elapsed-calc "%tt1%" "%tt2%"
More? )
15000

Command grouping works like this (apologies if you know this already!)

At the prompt you type an opening parenthesis ( + Enter. The command processor responds with More? and you type a command or program name & hit Enter & you get another More? prompt and so on until you type a closing parenthesis ) + Enter at which point the whole stored series of commands is executed in sequence almost as if they were in a batch file, with some differences obviously. (E.g. no multiline parenthetical expressions.)


Title: Re: Calculating using time
Post by: Frank on August 16, 2008, 04:51:04 AM
I think that the new elapsed-calc.bat works. but this:

for /f %%A in ('elapsed-calc.bat "%time1%" "%time2%"^>nul') do set elapsed=%%A

doesn't. the %elapsed% returns just a space (" ").
Using the previous version:

for /f %%A in ('elapsed-calc.bat %time1% %time2%') do set elapsed=%%A

does work, at least after 10:00am. I'll try it tomorrow morning also.

Thanks for the command grouping. I know about it (now).
Title: Re: Calculating using time
Post by: Dias de verano on August 16, 2008, 05:01:37 AM
Yes you are right.

The problem was the ^>nul which is not only unnecessary but harmful.

So the calling code looks this

for /f %%A in ('elapsed-calc.bat "%time1%" "%time2%"') do set elapsed=%%A

I just tested it

Title: Re: Calculating using time
Post by: Frank on August 16, 2008, 06:11:24 AM
Well done.
That did it.
Thanks a lot.