如何在batch file中获得两次之间的差异? 因为我想打印在HTML文件中。
我认为这是可能的,但事实并非如此。
Set "tijd=%time%" echo %tijd% echo %time%-%tijd%
结果:
11:07:48,85 11:16:58,99-11:07:48,85
但是我想要的是:
00:09:10,14
或9分10秒或550秒
@echo off rem Get start time: for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" ) rem Any process here... rem Get end time: for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" ) rem Get elapsed time: set /A elapsed=end-start rem Show elapsed time: set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100 if %mm% lss 10 set mm=0%mm% if %ss% lss 10 set ss=0%ss% if %cc% lss 10 set cc=0%cc% echo %hh%:%mm%:%ss%,%cc%
编辑2017-05-09: 添加更短的方法
我开发了一个较短的方法来获得相同的结果,所以我忍不住要在这里发表。 两个for
分隔时间部分的命令和三个用于在结果中插入前导零的if
命令由两个长的算术表达式替代,甚至可以组合成一个较长的行。
该方法包括直接将“HH:MM:SS.CC”格式的变量转换为将时间转换为厘秒的公式,相应地转换为下面给出的映射方案:
HH : MM : SS . CC (((10 HH %%100)*60+1 MM %%100)*60+1 SS %%100)*100+1 CC %%100
也就是说,插入(((10
开头,用%%100)*60+1
代替冒号%%100)*60+1
,用%%100)*100+1
代替点,最后插入%%100
;最后,计算结果字符串作为一个算术表达式,在时间变量中有两个不同的子字符串需要被替换,所以转换必须在两行中完成,为了获得一个经过的时间,使用(endTime)-(startTime)
表达式并替换两个时间字符串在同一行。
编辑2017/06/14: 增加了语言环境独立调整
@echo off setlocal EnableDelayedExpansion set "startTime=%time: =0%" set /P "=Any process here..." set "endTime=%time: =0%" rem Get elapsed time: set "end=!endTime:%time:~8,1%=%%100)*100+1!" & set "start=!startTime:%time:~8,1%=%%100)*100+1!" set /A "elap=((((10!end:%time:~2,1%=%%100)*60+1!%%100)-((((10!start:%time:~2,1%=%%100)*60+1!%%100)" rem Convert elapsed time to HH:MM:SS:CC format: set /A "cc=elap%%100+100,elap/=100,ss=elap%%60+100,elap/=60,mm=elap%%60+100,hh=elap/60+100" echo Start: %startTime% echo End: %endTime% echo Elapsed: %hh:~1%%time:~2,1%%mm:~1%%time:~2,1%%ss:~1%%time:~8,1%%cc:~1%
你可以在这个答案中查看这个方法的详细解释。
在这里回答: 如何使用Windows批处理文件来衡量控制台应用程序的性能?
下面的批次“程序”应该做你想做的。 请注意,它以毫秒为单位输出数据,而不是毫秒。 使用的命令的精确度仅为厘秒。
这是一个输出示例:
STARTTIME: 13:42:52,25 ENDTIME: 13:42:56,51 STARTTIME: 4937225 centiseconds ENDTIME: 4937651 centiseconds DURATION: 426 in centiseconds 00:00:04,26
这是批处理脚本:
@echo off setlocal rem The format of %TIME% is HH:MM:SS,CS for example 23:59:59,99 set STARTTIME=%TIME% rem here begins the command you want to measure dir /s > nul rem here ends the command you want to measure set ENDTIME=%TIME% rem output as time echo STARTTIME: %STARTTIME% echo ENDTIME: %ENDTIME% rem convert STARTTIME and ENDTIME to centiseconds set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100) set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100) rem calculating the duratyion is easy set /A DURATION=%ENDTIME%-%STARTTIME% rem we might have measured the time inbetween days if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME% rem now break the centiseconds down to hors, minutes, seconds and the remaining centiseconds set /A DURATIONH=%DURATION% / 360000 set /A DURATIONM=(%DURATION% - %DURATIONH%*360000) / 6000 set /A DURATIONS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000) / 100 set /A DURATIONHS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000 - %DURATIONS%*100) rem some formatting if %DURATIONH% LSS 10 set DURATIONH=0%DURATIONH% if %DURATIONM% LSS 10 set DURATIONM=0%DURATIONM% if %DURATIONS% LSS 10 set DURATIONS=0%DURATIONS% if %DURATIONHS% LSS 10 set DURATIONHS=0%DURATIONHS% rem outputing echo STARTTIME: %STARTTIME% centiseconds echo ENDTIME: %ENDTIME% centiseconds echo DURATION: %DURATION% in centiseconds echo %DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS% endlocal goto :EOF
Aacini代码的重新散列,因为您很可能将开始时间设置为一个变量,并希望保存该数据以进行输出:
@echo off rem ****************** MAIN CODE SECTION set STARTTIME=%TIME% rem Your code goes here (remove the ping line) ping -n 4 -w 1 127.0.0.1 >NUL set ENDTIME=%TIME% rem ****************** END MAIN CODE SECTION rem Change formatting for the start and end times for /F "tokens=1-4 delims=:.," %%a in ("%STARTTIME%") do ( set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" ) for /F "tokens=1-4 delims=:.," %%a in ("%ENDTIME%") do ( set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" ) rem Calculate the elapsed time by subtracting values set /A elapsed=end-start rem Format the results for output set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100 if %hh% lss 10 set hh=0%hh% if %mm% lss 10 set mm=0%mm% if %ss% lss 10 set ss=0%ss% if %cc% lss 10 set cc=0%cc% set DURATION=%hh%:%mm%:%ss%,%cc% echo Start : %STARTTIME% echo Finish : %ENDTIME% echo --------------- echo Duration : %DURATION%
输出:
Start : 11:02:45.92 Finish : 11:02:48.98 --------------- Duration : 00:00:03,06
根据以前的答案,这里是可重复使用的“程序”和计算经过时间的使用示例:
@echo off setlocal set starttime=%TIME% echo Start Time: %starttime% REM --------------------------------------------- REM --- PUT THE CODE YOU WANT TO MEASURE HERE --- REM --------------------------------------------- set endtime=%TIME% echo End Time: %endtime% call :elapsed_time %starttime% %endtime% duration echo Duration: %duration% endlocal echo on & goto :eof REM --- HELPER PROCEDURES --- :time_to_centiseconds :: %~1 - time :: %~2 - centiseconds output variable setlocal set _time=%~1 for /F "tokens=1-4 delims=:.," %%a in ("%_time%") do ( set /A "_result=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" ) endlocal & set %~2=%_result% goto :eof :centiseconds_to_time :: %~1 - centiseconds :: %~2 - time output variable setlocal set _centiseconds=%~1 rem now break the centiseconds down to hors, minutes, seconds and the remaining centiseconds set /A _h=%_centiseconds% / 360000 set /A _m=(%_centiseconds% - %_h%*360000) / 6000 set /A _s=(%_centiseconds% - %_h%*360000 - %_m%*6000) / 100 set /A _hs=(%_centiseconds% - %_h%*360000 - %_m%*6000 - %_s%*100) rem some formatting if %_h% LSS 10 set _h=0%_h% if %_m% LSS 10 set _m=0%_m% if %_s% LSS 10 set _s=0%_s% if %_hs% LSS 10 set _hs=0%_hs% set _result=%_h%:%_m%:%_s%.%_hs% endlocal & set %~2=%_result% goto :eof :elapsed_time :: %~1 - time1 - start time :: %~2 - time2 - end time :: %~3 - elapsed time output setlocal set _time1=%~1 set _time2=%~2 call :time_to_centiseconds %_time1% _centi1 call :time_to_centiseconds %_time2% _centi2 set /A _duration=%_centi2%-%_centi1% call :centiseconds_to_time %_duration% _result endlocal & set %~3=%_result% goto :eof
使用一个单一的功能,可以自定义计量单位或格式化。 每次该函数被调用时没有参数,我们重新开始初始时间。
@ECHO OFF ECHO. ECHO DEMO timer function ECHO -------------------- SET DELAY=4 :: First we call the function without any parameters to set the starting time CALL:timer :: We put some code we want to measure ECHO. ECHO Making some delay, please wait... ECHO. ping -n %DELAY% -w 1 127.0.0.1 >NUL :: Now we call the function again with the desired parameters CALL:timer elapsed_time ECHO by Default : %elapsed_time% CALL:timer elapsed_time "s" ECHO in Seconds : %elapsed_time% CALL:timer elapsed_time "anything" ECHO Formatted : %elapsed_time% (HH:MM:SS.CS) ECHO. PAUSE :: Elapsed Time Function :: ----------------------------------------------------------------------- :: The returned value is in centiseconds, unless you enter the parameters :: to be in another unit of measure or with formatted :: :: Parameters: :: <return> the returned value :: [formatted] s (for seconds), m (for minutes), h (for hours) :: anything else for formatted output :: ----------------------------------------------------------------------- :timer <return> [formatted] SetLocal EnableExtensions EnableDelayedExpansion SET _t=%time% SET _t=%_t::0=: % SET _t=%_t:,0=, % SET _t=%_t:.0=. % SET _t=%_t:~0,2% * 360000 + %_t:~3,2% * 6000 + %_t:~6,2% * 100 + %_t:~9,2% SET /A _t=%_t% :: If we call the function without parameters is defined initial time SET _r=%~1 IF NOT DEFINED _r ( EndLocal & SET TIMER_START_TIME=%_t% & GOTO :EOF ) SET /A _t=%_t% - %TIMER_START_TIME% :: In the case of wanting a formatted output SET _f=%~2 IF DEFINED _f ( IF "%_f%" == "s" ( SET /A "_t=%_t% / 100" ) ELSE ( IF "%_f%" == "m" ( SET /A "_t=%_t% / 6000" ) ELSE ( IF "%_f%" == "h" ( SET /A "_t=%_t% / 360000" ) ELSE ( SET /A "_h=%_t% / 360000" SET /A "_m=(%_t% - !_h! * 360000) / 6000" SET /A "_s=(%_t% - !_h! * 360000 - !_m! * 6000) / 100" SET /A "_cs=(%_t% - !_h! * 360000 - !_m! * 6000 - !_s! * 100)" IF !_h! LSS 10 SET "_h=0!_h!" IF !_m! LSS 10 SET "_m=0!_m!" IF !_s! LSS 10 SET "_s=0!_s!" IF !_cs! LSS 10 SET "_cs=0!_cs!" SET "_t=!_h!:!_m!:!_s!.!_cs!" SET "_t=!_t:00:=!" ) ) ) ) EndLocal & SET %~1=%_t% goto :EOF
一个延迟94秒的测试
DEMO timer function -------------------- Making some delay, please wait... by Default : 9404 in Seconds : 94 Formatted : 01:34.05 (HH:MM:SS.CS) Presione una tecla para continuar . . .
修正了Gynnad领先的0
问题。 我用两条线固定它
SET STARTTIME=%STARTTIME: =0% SET ENDTIME=%ENDTIME: =0%
完整脚本( CalculateTime.cmd
):
@ECHO OFF :: FUNCTIONS :__START_TIME_MEASURE SET STARTTIME=%TIME% SET STARTTIME=%STARTTIME: =0% EXIT /B 0 :__STOP_TIME_MEASURE SET ENDTIME=%TIME% SET ENDTIME=%ENDTIME: =0% SET /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100) SET /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100) SET /A DURATION=%ENDTIME%-%STARTTIME% IF %DURATION% == 0 SET TIMEDIFF=00:00:00,00 && EXIT /B 0 IF %ENDTIME% LSS %STARTTIME% SET /A DURATION=%STARTTIME%-%ENDTIME% SET /A DURATIONH=%DURATION% / 360000 SET /A DURATIONM=(%DURATION% - %DURATIONH%*360000) / 6000 SET /A DURATIONS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000) / 100 SET /A DURATIONHS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000 - %DURATIONS%*100) IF %DURATIONH% LSS 10 SET DURATIONH=0%DURATIONH% IF %DURATIONM% LSS 10 SET DURATIONM=0%DURATIONM% IF %DURATIONS% LSS 10 SET DURATIONS=0%DURATIONS% IF %DURATIONHS% LSS 10 SET DURATIONHS=0%DURATIONHS% SET TIMEDIFF=%DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS% EXIT /B 0 :: USAGE :: Start Measuring CALL :__START_TIME_MEASURE :: Print Message on Screen without Linefeed ECHO|SET /P=Execute Job... :: Some Time pending Jobs here :: '> NUL 2>&1' Dont show any Messages or Errors on Screen MyJob.exe > NUL 2>&1 :: Stop Measuring CALL :__STOP_TIME_MEASURE :: Finish the Message 'Execute Job...' and print measured Time ECHO [Done] (%TIMEDIFF%) :: Possible Result :: Execute Job... [Done] (00:02:12,31) :: Between 'Execute Job... ' and '[Done] (00:02:12,31)' the Job will be executed
Aacini最新的代码展示了一个非常棒的变量替换方法。
这是一个耻辱,这不是区域格式证明 – 它失败了这么多层次。
这里有一个简短的修复,保持替换+数学方法不变:
@echo off setlocal EnableDelayedExpansion set "startTime=%time: =0%" & rem AveYo: fix single digit hour set /P "=Any process here..." set "endTime=%time: =0%" & rem AveYo: fix single digit hour rem Aveyo: Regional format fix with just one aditional line for /f "tokens=1-3 delims=0123456789" %%i in ("%endTime%") do set "COLON=%%i" & set "DOT=%%k" rem Get elapsed time: set "end=!endTime:%DOT%=%%100)*100+1!" & set "start=!startTime:%DOT%=%%100)*100+1!" set /A "elap=((((10!end:%COLON%=%%100)*60+1!%%100)-((((10!start:%COLON%=%%100)*60+1!%%100)" rem Aveyo: Fix 24 hours set /A "elap=!elap:-=8640000-!" rem Convert elapsed time to HH:MM:SS:CC format: set /A "cc=elap%%100+100,elap/=100,ss=elap%%60+100,elap/=60,mm=elap%%60+100,hh=elap/60+100" echo Start: %startTime% echo End: %endTime% echo Elapsed: %hh:~1%%COLON%%mm:~1%%COLON%%ss:~1%%DOT%%cc:~1% & rem AveYo: display as regional pause
“精益和平均”的定时器与区域格式,24小时和混合输入的支持
适应Aacini的替代方法主体,没有IF,只有一个FOR(我的区域修复)
1:将文件timer.bat放置在%PATH%或当前目录的某处
@echo off & rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof (if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n) set "TE=!timer_end:%DE%=%%100)*100+1!" & set "TS=!timer_set:%DS%=%%100)*100+1!" set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!" set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100" set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value! endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof
用法:
定时器 &回声start_cmds&超时/吨3&回声end_cmds& 定时器
定时器和计时器 “23:23:23,00”
定时器 “23:23:23,00”和计时器
定时器 “13.23.23,00”和计时器 “03:03:03.00”
定时器和计时器 “0:00:00.00”no&cmd / v:on / c直到午夜=!timer_end!
输入现在可以混合,对于那些不太可能的,但是在执行期间可能的时间格式改变
2:功能:与批处理脚本捆绑在一起的定时器 (下面的示例用法):
@echo off set "TIMER=call :timer" & rem short macro echo. echo EXAMPLE: call :timer timeout /t 3 >nul & rem Any process here.. call :timer echo. echo SHORT MACRO: %TIMER% & timeout /t 1 & %TIMER% echo. echo TEST INPUT: set "start=22:04:04.58" set "end=04.22.44,22" echo %start% ~ start & echo %end% ~ end call :timer "%start%" call :timer "%end%" echo. %TIMER% & %TIMER% "00:00:00.00" no echo UNTIL MIDNIGHT: %timer_end% echo. pause exit /b
::测试它,复制粘贴上面和下面的代码部分
rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support :timer Usage " call :timer [input - optional] [no - optional]" :i Result printed on second call, saved to timer_end if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof (if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n) set "TE=!timer_end:%DE%=%%100)*100+1!" & set "TS=!timer_set:%DS%=%%100)*100+1!" set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!" set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100" set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value! endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof
回声是打印变量值的命令,可能不能处理任何数学。
但是您可以查看下面的链接来获得解决方案。
批处理文件需要多长时间才能执行?