Windows批处理文件中的计时器

20

有人能指点我如何在Windows批处理文件中添加一个计时器吗?我需要追踪我的批处理从开始运行的时间。


你使用的是哪个版本的DOS? - TZHX
我正在使用版本5.2.379。 - JVIDIN
7个回答

19

重构了计算经过时间的代码:

  • 计算代码更为简洁,
  • 对于小于0.1秒的经过时间提供了填充,
  • 使用标签使其可被多次调用,并将计时器代码分组。

可重复使用的代码:

: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

调用代码:

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

注意在数字前加上"1"前缀,以避免将零填充的值(08和09)解释为八进制值,还要使用适当的常量进行校正。由于这可能会对核心计算造成困惑,可以考虑以下替代一行 for 语句的方法:

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

12

一个简化版本,以秒为单位显示经过的时间。

@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.

但我有一个一个半小时的脚本。如何将其转换为分钟而不是秒?如果对您来说太简单了,那我很抱歉! - Adrian Cumpanasu
3
谢谢@migonzalvar,这正是我需要的。对于好奇的人来说,你不能一次检索两个数字来表示分钟和秒,因为前导0会导致该数字被解释为八进制。对于小时来说,它可以工作是因为有一个前导空格,而不是0。在">nul"之前需要空格,因为(例如)"2>nul"表示重定向stderr。 (哦,那些尾随的^符号转义换行符。) - yoyo

3
据我所知,在批处理文件中没有明确的“timer”命令可用,但有一个相当简单的解决方案。在批处理文件顶部记录当前时间(开始时间),在批处理文件末尾记录当前时间(结束时间),然后比较这两个时间。像这样的东西应该可以做到(它似乎过于复杂,但它处理了大多数时间的怪癖):
:: 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

另外一种选择 #1:Windows Server 2k3 资源工具包包括 timeit.exe,您可以使用它来显示脚本的各种性能统计信息。

另外一种选择 #2:您可以比上面发布的脚本更简单地执行以下步骤:

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

然而,这并不能给你以秒为单位的执行时间。

2

这个定时器非常准确,从5开始倒计时。但我不确定你如何将其添加到你的代码中。注意:这是一个非常基本的批处理定时器,其他答案可能更好,但这只是一种用简单代码设计自己的批处理定时器的快速方式。

@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

同时,要更改此定时器开始的时间,请将set /a time=5更改为set /a time=(您想要开始的任何时间)


2

按照以下结构编写您的程序:

@echo off
setlocal enabledelyedexpansion

set T[1]=%time%

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

set T[2]=%time%
call TIMER

这是TIMER.BAT程序的代码。将其保存为一个单独的文件,放在您路径中的某个地方。

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!

1

你可以试试这个(更短一点..)

@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 ------------- */

0

我认为最好的选择是使用PowerShell

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

rem some commands

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

这将打印以毫秒为单位的经过时间


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接