You are not logged in.
I've googled this already, but results are scarce, and those results are dead links.
Basically I'm looking for a cmd app that would start a timer/chrono until it is told to stop. Once stopped, it would tell the time between start/stop
Example:
12:00:00 - timer.exe start
>timer started
12:10:52 - timer.exe stop
>652 [seconds.ms]
Offline
How about this?
@echo off
setlocal
set time=
set time=%time: =0%
set stamp.file=%temp%\%~n0.stamp
if /i "%~1" EQU "start" call :make.stamp
if /i "%~1" EQU "stop" call :read.stamp stop
if /i "%~1" EQU "lap" call :read.stamp lap
if "%~1" EQU "" call :status
endlocal
goto :EOF
:status
if exist "%stamp.file%" (
if /i "%~1" NEQ "/q" echo:Timer is active.
exit /b 0
)
echo:Timer is not active.
exit /b 1
:make.stamp
if exist "%stamp.file%" call :read.stamp stop
set start.time=%time%
(echo:%start.time%) > "%stamp.file%"
echo:Timer started %start.time%
goto :EOF
:read.stamp
call :status /q
if errorlevel 1 goto :EOF
set stop.time=%time%
set /p start.time=< "%stamp.file%"
echo:Timer started %start.time%
echo:Timer %1ped %stop.time%
if %1 EQU stop del "%stamp.file%"
call :calc.time.code %start.time%
set start.time.code=%errorlevel%
call :calc.time.code %stop.time%
set stop.time.code=%errorlevel%
set /a diff.time.code=stop.time.code - start.time.code
if %diff.time.code% LSS 0 set /a diff.time.code+=(24 * 60 * 60 * 100)
setlocal
set /a hs=diff.time.code %% 100
set /a diff.time.code/=100
set /a ss=diff.time.code %% 60
set /a diff.time.code/=60
set /a mm=diff.time.code %% 60
set /a diff.time.code/=60
set /a hh=diff.time.code
set hh=0%hh%
set mm=0%mm%
set ss=0%ss%
set hs=0%hs%
endlocal & set diff.time=%hh:~-2%:%mm:~-2%:%ss:~-2%.%hs:~-2%
echo %diff.time.code% hundredths of a second
echo %diff.time%
goto :EOF
:calc.time.code
setlocal
for /f "usebackq tokens=1,2,3,4 delims=:." %%a in ('%1') do (
set hh=%%a
set mm=%%b
set ss=%%c
set hs=%%d
)
set /a hh=((%hh:~0,1% * 10) + %hh:~1,1%) * 60 * 60 * 100
set /a mm=((%mm:~0,1% * 10) + %mm:~1,1%) * 60 * 100
set /a ss=((%ss:~0,1% * 10) + %ss:~1,1%) * 100
set /a hs=((%hs:~0,1% * 10) + %hs:~1,1%)
set /a time.code=hh + mm + ss + hs
endlocal & exit /b %time.code%
Use it with "start", "stop" and "lap" as parameters (using "lap" will get the time since start, without stopping the counter).
It'll handle crossing midnight but has no concept of date, so timing events >1 day won't work. It shouldn't be too difficult to integrate the DATEMATH script to deal with that though.
EDIT: Running without parameters will display a brief message about whether or not the timer is active.
EDIT: Fixed ineffective crossing-midnight code. Thanks RG.
Last edited by bluesxman (05 Mar 2010 16:24)
cmd | *sh | Ruby | Chef
Offline
Nice !
Windows Shell Scripting and InstallShield
Offline
How about this?
Use it with "start", "stop" and "lap" as parameters (using "lap" will get the time since start, without stopping the counter).It'll handle crossing midnight but has no concept of date, so timing events >1 day won't work. It shouldn't be too difficult to integrate the DATEMATH script to deal with that though.
I see what you did there
But wow, that little tool will come in handy for all sorts of things.
I understand how it can't handle dates, thus crossing 24h resets the timer to 0, but that shouldn't be an issue, ever, at all.
Bluesxman is credit to team!
Offline
I've made a couple of minor tweaks -- code above updated.
Last edited by bluesxman (05 Mar 2010 01:07)
cmd | *sh | Ruby | Chef
Offline
Very practical! To correctly handle the crossing of midnight the line
if diff.time.code LSS 0 set /a diff.time.code*=-1
should be
if diff.time.code LSS 0 set /a diff.time.code+=8640000
This is easily tested by:
Set date/time back
Start timer
Reset date/time
Stop timer
Windows Shell Scripting and InstallShield
Offline
Yeah you have a point there -- thanks for drawing attention to my *cough* thorough testing
In fact that whole line was never going to work cause I managed to miss the "%" out (a bug you've duplicated in your correction!)
All corrected above.
Last edited by bluesxman (05 Mar 2010 16:25)
cmd | *sh | Ruby | Chef
Offline
Wow thanks guys!
You guys should create some sort of database of pre-made batch scripts like this.
Saves a lot of time when you're working on a project, and you need a certain function
Offline
Wow thanks guys!
You guys should create some sort of database of pre-made batch scripts like this.
Saves a lot of time when you're working on a project, and you need a certain function
This is such a handy script, I've just put a copy on the main site to make it easier to find. With a credit to bluesxman and a link back to this thread.
https://ss64.com/nt/syntax-timer.html
Offline
This is such a handy script, I've just put a copy on the main site to make it easier to find. With a credit to bluesxman and a link back to this thread.
https://ss64.com/nt/syntax-timer.html
Whoop!
Reading that again 8 years on, my first thought -- needs comments.
cmd | *sh | Ruby | Chef
Offline
I am getting :
call timer.cmd stop
Timer started 09:02:33,94
Timer stopped 09:03:04,54
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
3100 hundredths of a second
00:00:31.00
How to fix it?
Offline
I think it's due to the delimiting characters in your time string (presumably due to your regional settings). It's broadly expecting "hh:mm:ss.hs" but you have a comma instead of the dot.
You could workaround that by changing this line:
for /f "usebackq tokens=1,2,3,4 delims=:." %%a in ('%1') do (
To this:
for /f "usebackq tokens=1,2,3,4 delims=:.," %%a in ('%1') do (
It could do with a more robust solution, but I think that will work for you for now.
cmd | *sh | Ruby | Chef
Offline
@bluesxman
Thanks, probably because of my windows locale setting.
[Edit]
Hmm, i am still getting the error :
call timer.cmd stop
Timer started 20:19:45,77
Timer stopped 20:19:51,89
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
600 hundredths of a second
00:00:06.00
Last edited by nanobot (21 Jun 2019 14:21)
Offline
nanobot, if you run
Echo %time%
what does the output look like?
Offline
the result for example :
21:01:27,44
21:01:38,21
Offline
Try changing that line to:
for /f "usebackq tokens=1,2,3,4 delims=:.," %%a in ('echo "%1"') do (
Offline
Hmm, still getting the same error , could you please try to set up your windows locale as "Indonesia" and try it if you can reproduce my condition?
Timer started 02:41:34,45
Timer stopped 02:41:37,48
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
300 hundredths of a second
00:00:03.00
Offline
I tried that but for me the locale doesnt affect the output of %time%
what does this give you:
for /f "usebackq tokens=1,2,3,4 delims=:. " %%a in ('%1') do (
Offline
Hmm, yes the same , i was saw your deleted? post about the "space" replacement.
Scratching my head over these, hmm.
Offline
OK, try changing the whole calc.time.code function as follows (NB I have not tested this code as I'm not near a Windows machine):
:calc.time.code
if not defined t_delims for /f "tokens=1,2,3,4,5 delims=0123456789" %%v in ("%1") do set "t_delims=%%v%%w%%x%%y%%z"
setlocal
for /f "tokens=1,2,3,4 delims=%t_delims% " %%a in ("%1") do (
set hh=%%a
set mm=%%b
set ss=%%c
set hs=%%d
)
set /a hh=((%hh:~0,1% * 10) + %hh:~1,1%) * 60 * 60 * 100
set /a mm=((%mm:~0,1% * 10) + %mm:~1,1%) * 60 * 100
set /a ss=((%ss:~0,1% * 10) + %ss:~1,1%) * 100
set /a hs=((%hs:~0,1% * 10) + %hs:~1,1%)
set /a time.code=hh + mm + ss + hs
endlocal & exit /b %time.code%
Last edited by bluesxman (24 Jun 2019 10:09)
cmd | *sh | Ruby | Chef
Offline
@bluesxman
Thanks but it looks like the same error :
Timer started 17:42:53,66
Timer stopped 17:42:56,02
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
300 hundredths of a second
00:00:03.00
Offline
@nanobot, which version of Windows are you running?
Offline
@Simon Sheppard
Windows 10 Enterprise x64
Version 1903, OS Build 18362.175
Last edited by nanobot (24 Jun 2019 20:01)
Offline
Please can you post the entire script you are running?
cmd | *sh | Ruby | Chef
Offline
Here it is :
@echo off
setlocal
set time=
set time=%time: =0%
set stamp.file=%temp%\%~n0.stamp
if /i "%~1" EQU "start" call :make.stamp
if /i "%~1" EQU "stop" call :read.stamp stop
if /i "%~1" EQU "lap" call :read.stamp lap
if "%~1" EQU "" call :status
endlocal
goto :EOF
:status
if exist "%stamp.file%" (
if /i "%~1" NEQ "/q" echo:Timer is active.
exit /b 0
)
echo:Timer is not active.
exit /b 1
:make.stamp
if exist "%stamp.file%" call :read.stamp stop
set start.time=%time%
(echo:%start.time%) > "%stamp.file%"
echo:Timer started %start.time%
goto :EOF
:read.stamp
call :status /q
if errorlevel 1 goto :EOF
set stop.time=%time%
set /p start.time=< "%stamp.file%"
echo:Timer started %start.time%
echo:Timer %1ped %stop.time%
if %1 EQU stop del "%stamp.file%"
call :calc.time.code %start.time%
set start.time.code=%errorlevel%
call :calc.time.code %stop.time%
set stop.time.code=%errorlevel%
set /a diff.time.code=stop.time.code - start.time.code
if %diff.time.code% LSS 0 set /a diff.time.code+=(24 * 60 * 60 * 100)
setlocal
set /a hs=diff.time.code %% 100
set /a diff.time.code/=100
set /a ss=diff.time.code %% 60
set /a diff.time.code/=60
set /a mm=diff.time.code %% 60
set /a diff.time.code/=60
set /a hh=diff.time.code
set hh=0%hh%
set mm=0%mm%
set ss=0%ss%
set hs=0%hs%
endlocal & set diff.time=%hh:~-2%:%mm:~-2%:%ss:~-2%.%hs:~-2%
echo %diff.time.code% hundredths of a second
echo %diff.time%
goto :EOF
:calc.time.code
if not defined t_delims for /f "tokens=1,2,3,4,5 delims=0123456789" %%v in ("%1") do set "t_delims=%%v%%w%%x%%y%%z"
setlocal
for /f "tokens=1,2,3,4 delims=%t_delims% " %%a in ("%1") do (
set hh=%%a
set mm=%%b
set ss=%%c
set hs=%%d
)
set /a hh=((%hh:~0,1% * 10) + %hh:~1,1%) * 60 * 60 * 100
set /a mm=((%mm:~0,1% * 10) + %mm:~1,1%) * 60 * 100
set /a ss=((%ss:~0,1% * 10) + %ss:~1,1%) * 100
set /a hs=((%hs:~0,1% * 10) + %hs:~1,1%)
set /a time.code=hh + mm + ss + hs
endlocal & exit /b %time.code%
Offline
OK, maybe we need some debug. Please can you change it as follows and post the output produced as before?
:calc.time.code
@echo on
echo:[[%1]]
if not defined t_delims for /f "tokens=1,2,3,4,5 delims=0123456789" %%v in ("%1") do set "t_delims=%%v%%w%%x%%y%%z"
set t_delims
setlocal
for /f "tokens=1,2,3,4 delims=%t_delims% " %%a in ("%1") do (
set hh=%%a
set mm=%%b
set ss=%%c
set hs=%%d
)
set hh
set mm
set ss
set hs
set /a hh=((%hh:~0,1% * 10) + %hh:~1,1%) * 60 * 60 * 100
set /a mm=((%mm:~0,1% * 10) + %mm:~1,1%) * 60 * 100
set /a ss=((%ss:~0,1% * 10) + %ss:~1,1%) * 100
set /a hs=((%hs:~0,1% * 10) + %hs:~1,1%)
set hh
set mm
set ss
set hs
set /a time.code=hh + mm + ss + hs
set time.code
@echo off
endlocal & exit /b %time.code%
cmd | *sh | Ruby | Chef
Offline
here we go :
C:\Q>call timer.cmd start
Timer started 19:54:49,87
C:\Q>call timer.cmd stop
Timer started 19:54:49,87
Timer stopped 19:54:55,07
C:\Q>echo:[[19:54:49]]
[[19:54:49]]
C:\Q>if not defined t_delims for /F "tokens=1,2,3,4,5 delims=0123456789" %v in ("19:54:49") do set "t_delims=%v%w%x%y%z"
C:\Q>set "t_delims=::"
C:\Q>set t_delims
t_delims=::
C:\Q>setlocal
C:\Q>for /F "tokens=1,2,3,4 delims=:: " %a in ("19:54:49") do (
set hh=%a
set mm=%b
set ss=%c
set hs=%d
)
C:\Q>(
set hh=19
set mm=54
set ss=49
set hs=
)
C:\Q>set hh
hh=19
C:\Q>set mm
mm=54
C:\Q>set ss
ss=49
C:\Q>set hs
Environment variable hs not defined
C:\Q>set /a hh=((1 * 10) + 9) * 60 * 60 * 100
C:\Q>set /a mm=((5 * 10) + 4) * 60 * 100
C:\Q>set /a ss=((4 * 10) + 9) * 100
C:\Q>set /a hs=((~0,1hs:~1,1)
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
C:\Q>set hh
hh=6840000
C:\Q>set mm
mm=324000
C:\Q>set ss
ss=4900
C:\Q>set hs
Environment variable hs not defined
C:\Q>set /a time.code=hh + mm + ss + hs
C:\Q>set time.code
time.code=7168900
C:\Q>echo:[[19:54:55]]
[[19:54:55]]
C:\Q>if not defined t_delims for /F "tokens=1,2,3,4,5 delims=0123456789" %v in ("19:54:55") do set "t_delims=%v%w%x%y%z"
C:\Q>set t_delims
t_delims=::
C:\Q>setlocal
C:\Q>for /F "tokens=1,2,3,4 delims=:: " %a in ("19:54:55") do (
set hh=%a
set mm=%b
set ss=%c
set hs=%d
)
C:\Q>(
set hh=19
set mm=54
set ss=55
set hs=
)
C:\Q>set hh
hh=19
C:\Q>set mm
mm=54
C:\Q>set ss
ss=55
C:\Q>set hs
Environment variable hs not defined
C:\Q>set /a hh=((1 * 10) + 9) * 60 * 60 * 100
C:\Q>set /a mm=((5 * 10) + 4) * 60 * 100
C:\Q>set /a ss=((5 * 10) + 5) * 100
C:\Q>set /a hs=((~0,1hs:~1,1)
Invalid number. Numeric constants are either decimal (17),
hexadecimal (0x11), or octal (021).
C:\Q>set hh
hh=6840000
C:\Q>set mm
mm=324000
C:\Q>set ss
ss=5500
C:\Q>set hs
Environment variable hs not defined
C:\Q>set /a time.code=hh + mm + ss + hs
C:\Q>set time.code
time.code=7169500
600 hundredths of a second
00:00:06.00
Offline
Ah, OK I think see the problem. Try this version:
@echo off
setlocal
set time=
set time=%time: =0%
set stamp.file=%temp%\%~n0.stamp
if /i "%~1" EQU "start" call :make.stamp
if /i "%~1" EQU "stop" call :read.stamp stop
if /i "%~1" EQU "lap" call :read.stamp lap
if "%~1" EQU "" call :status
endlocal
goto :EOF
:status
if exist "%stamp.file%" (
if /i "%~1" NEQ "/q" echo:Timer is active.
exit /b 0
)
echo:Timer is not active.
exit /b 1
:make.stamp
if exist "%stamp.file%" call :read.stamp stop
set start.time=%time%
(echo:%start.time%) > "%stamp.file%"
echo:Timer started %start.time%
goto :EOF
:read.stamp
call :status /q
if errorlevel 1 goto :EOF
set stop.time=%time%
set /p start.time=< "%stamp.file%"
echo:Timer started %start.time%
echo:Timer %1ped %stop.time%
if %1 EQU stop del "%stamp.file%"
call :calc.time.code "%start.time%"
set start.time.code=%errorlevel%
call :calc.time.code "%stop.time%"
set stop.time.code=%errorlevel%
set /a diff.time.code=stop.time.code - start.time.code
if %diff.time.code% LSS 0 set /a diff.time.code+=(24 * 60 * 60 * 100)
setlocal
set /a hs=diff.time.code %% 100
set /a diff.time.code/=100
set /a ss=diff.time.code %% 60
set /a diff.time.code/=60
set /a mm=diff.time.code %% 60
set /a diff.time.code/=60
set /a hh=diff.time.code
set hh=0%hh%
set mm=0%mm%
set ss=0%ss%
set hs=0%hs%
endlocal & set diff.time=%hh:~-2%:%mm:~-2%:%ss:~-2%.%hs:~-2%
echo %diff.time.code% hundredths of a second
echo %diff.time%
goto :EOF
:calc.time.code
if not defined t_delims for /f "tokens=1,2,3,4,5 delims=0123456789" %%v in ("%~1") do set "t_delims=%%v%%w%%x%%y%%z"
setlocal
for /f "tokens=1,2,3,4 delims=%t_delims% " %%a in ("%~1") do (
set hh=%%a
set mm=%%b
set ss=%%c
set hs=%%d
)
set /a hh=((%hh:~0,1% * 10) + %hh:~1,1%) * 60 * 60 * 100
set /a mm=((%mm:~0,1% * 10) + %mm:~1,1%) * 60 * 100
set /a ss=((%ss:~0,1% * 10) + %ss:~1,1%) * 100
set /a hs=((%hs:~0,1% * 10) + %hs:~1,1%)
set /a time.code=hh + mm + ss + hs
endlocal & exit /b %time.code%
cmd | *sh | Ruby | Chef
Offline
@bluesxman
You are truly a savant!, works fine now :
Timer started 17:47:13,48
Timer stopped 17:47:15,86
238 hundredths of a second
00:00:02.38
Thanks a lot, btw what was the problems?
Offline
Glad we finally got there!
The problem was that the code wasn't protecting the time string when calling the sub routine, it was previously like so:
call :calc.time.code %start.time%
Apparently CMD was interpreting the comma in your localised time as a word delimiter.
So when passing a %start.time% as "12:34:56,78" it was actually being treated as "12:34:56 78". The sub routine is only expecting a single parameter, so the hundredths of a second were lost, causing the errors.
The fix I applied was to protect the string with quotes for the call
e.g.
call :calc.time.code "%start.time%"
And then remove the quotes again within the sub routine.
e.g.
for /f "tokens=1,2,3,4 delims=%t_delims% " %%a in ("%~1") do (
(the ~ in %~1 removes the quotes again)
Simon: could probably do with updating the ss64.com page with this more robust implementation
Last edited by bluesxman (26 Jun 2019 13:43)
cmd | *sh | Ruby | Chef
Offline