如何编写脚本来计算脚本完成的时间?
我认为情况确实如此,但显然不是......
@echo off
set starttime=%time%
set endtime=%time%
REM do stuff here
set /a runtime=%endtime%-%starttime%
echo Script took %runtime% to complete
答案 0 :(得分:38)
有关原始批处理文件的两件事情。 但从长远来看都不会有所帮助。
无论您的基准测试方法是什么,请确保在操作之前捕获的开始时间,并在操作之后捕获结束时间。你的样本没有这样做。
%time%
评估为“12:34:56.78”,SET /A
命令无法减去这些。您需要一个生成简单标量时间戳的命令。
我打算说它无法完成,但是批处理语言比它的功能强大得多,所以这里有一个简单的TIMER.BAT实现。为了记录,Pax打败了我的答案,显示我在摆弄时字符串分裂,JohannesRössel建议将算术移到测量区域之外:
@echo off
setlocal
rem Remeber start time. Note that we don't look at the date, so this
rem calculation won't work right if the program run spans local midnight.
set t0=%time: =0%
rem do something here.... but probably with more care about quoting.
rem specifically, odd things will happen if any arguments contain
rem precent signs or carets and there may be no way to prevent it.
%*
rem Capture the end time before doing anything else
set t=%time: =0%
rem make t0 into a scaler in 100ths of a second, being careful not
rem to let SET/A misinterpret 08 and 09 as octal
set /a h=1%t0:~0,2%-100
set /a m=1%t0:~3,2%-100
set /a s=1%t0:~6,2%-100
set /a c=1%t0:~9,2%-100
set /a starttime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%
rem make t into a scaler in 100ths of a second
set /a h=1%t:~0,2%-100
set /a m=1%t:~3,2%-100
set /a s=1%t:~6,2%-100
set /a c=1%t:~9,2%-100
set /a endtime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%
rem runtime in 100ths is now just end - start
set /a runtime = %endtime% - %starttime%
set runtime = %s%.%c%
echo Started at %t0%
echo Ran for %runtime%0 ms
你可以通过不打扰第二部分的第100个部分来简化算术并且更加诚实地对待它的整体准确性。假设您有一个睡眠命令或其他时间浪费,它就在行动中:
C:> TIMER SLEEP 3
Script took 3000 ms to complete
C:>
修改:我修改了评论中建议的代码及其说明。
我认为当NT团队用CMD.EXE取代COMMAND.COM时,他们认为他们不会因为它与众不同而逃脱。但实际上,它几乎是一种全新的语言。如果启用了扩展,许多旧的收藏命令都有新功能。
其中一个是SETLOCAL
,它可以防止变量修改调用者的环境。另一个是SET /A
,它为您提供了大量的算术。我在这里使用的主要技巧是新的子字符串提取语法,其中%t:~3,2%
表示从名为t
的变量的值的偏移量3开始的两个字符。
对于一个真正令人震惊的人,请查看set的完整描述(在提示时尝试SET /?
)如果这不会吓到你,请查看FOR /?
并注意它可以解析文件中的文字......
编辑2 修复了Frankie在评论中报告的包含08
或09
的时间字段的错误处理问题。调整了几件事,并添加了一些评论。
请注意,这里有一个明显的疏忽,我可能不会解决。如果命令在不同的日期开始而不是结束,它将无法工作。也就是说,它会做一些与时间相关的数学并报告差异,但差异并不大。
修复它至少可以警告这种情况很容易。修复它以做正确的事情更难。
编辑3:修正了单个数字小时未正确设置%h%的错误。这是由于%time%返回“9:01:23.45”。注意空间。使用%time:= 0%将空格替换为前导零,并且%h%将被正确设置。仅当脚本从一个数字小时运行到下一个小时时才会出现此错误。
答案 1 :(得分:4)
这是切向的,但它可能会帮助你。
Microsoft有一个timeit.exe程序,它或多或少类似于unix'time'命令的增强版本。它来自Windows Server 2003 Resource Kit,它几乎取代了我想要做的事情,就像你建议的那样。
值得一看。
答案 2 :(得分:3)
优秀的小常规。但是,如果计算跨越两天,则计算不正确。 结果需要从24小时减去(8640000厘秒)。
同时删除相关行中的一个重复'set'命令。
请注意,区域设置会影响TIME函数的格式,小数是英国的一个完整停止而不是逗号。
行
我们可能已经测量了几天之间的时间if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%
需要改为
我们可能已经测量了几天的时间if %ENDTIME% LSS %STARTTIME% set /A DURATION=8640000 - (%STARTTIME% - %ENDTIME%)
答案 3 :(得分:2)
我个人的偏好是安装Cygwin并使用time
命令但是,如果您实际 将其作为批处理文件执行,则不能只是减去字符串,你必须将它们视为零件。
以下脚本将为10秒的ping命令计时,该命令能够越过单日边界而不会被负数绑定。略微增强将允许它跨越多天的界限。
@echo off
setlocal enableextensions enabledelayedexpansion
set starttime=%time%
ping -n 11 127.0.0.1 >nul: 2>nul:
set endtime=%time%
set /a hrs=%endtime:~0,2%
set /a hrs=%hrs%-%starttime:~0,2%
set /a mins=%endtime:~3,2%
set /a mins=%mins%-%starttime:~3,2%
set /a secs=%endtime:~6,2%
set /a secs=%secs%-%starttime:~6,2%
if %secs% lss 0 (
set /a secs=!secs!+60
set /a mins=!mins!-1
)
if %mins% lss 0 (
set /a mins=!mins!+60
set /a hrs=!hrs!-1
)
if %hrs% lss 0 (
set /a hrs=!hrs!+24
)
set /a tot=%secs%+%mins%*60+%hrs%*3600
echo End = %endtime%
echo Start = %starttime%
echo Hours = %hrs%
echo Minutes = %mins%
echo Seconds = %secs%
echo Total = %tot%
endlocal
答案 4 :(得分:2)
查看此脚本,该脚本将通过WMI检索时间,因此它是独立的区域设置。
@echo off
::::::::::::::::::::::::::::::::::::::::::
:: TimeDiff v1.00 by LEVENTE ROG ::
:: www.thesysadminhimself.com ::
::::::::::::::::::::::::::::::::::::::::::
::[ EULA ]:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Feel free to use this script. The code can be redistributed ::
:: and edited, but please keep the credits. ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::[ CHANGELOG ]::::::::::::::
:: v1.00 - First Version ::
:::::::::::::::::::::::::::::
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
set Milisecond=%time:~9,2%
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
::
::
:: PUT COMMANDS HERE
ping www.thesysadminhimself.com
::
::
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
set Day=%%A
set Hour=%%B
set Minute=%%C
set Second=%%D
)
set Milisecond=%time:~9,2%
set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
set /a Diff=%End%-%Start%
set /a DiffMS=%Diff%%%100
set /a Diff=(%Diff%-%DiffMS%)/100
set /a DiffSec=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffMin=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffHrs=%Diff%
:: format with leading zeroes
if %DiffMS% LSS 10 set DiffMS=0%DiffMS!%
if %DiffSec% LSS 10 set DiffMS=0%DiffSec%
if %DiffMin% LSS 10 set DiffMS=0%DiffMin%
if %DiffHrs% LSS 10 set DiffMS=0%DiffHrs%
echo %DiffHrs%:%DiffMin%:%DiffSec%.%DiffMS%
答案 5 :(得分:1)
你不能直接在批处理脚本中进行时间算术,所以你需要一个外部程序来计算时差,或者提取每个部分的时间并以这种方式算术。
查看this forum thread的底部,了解如何执行后者的示例。摘录于此:
@echo off cls REM ================================================== ====== REM = Setting Date Time Format = REM ================================================== ====== set DT=%DATE% %TIME% set year=%DT:~10,4% set mth=%DT:~4,2% set date=%DT:~7,2% set hour=%DT:~15,2% set min=%DT:~18,2% set sec=%DT:~21,2% set newDT=%year%_%mth%_%date% %hour%%min%%sec% set hour=14 set min=10 REM =============================== REM = Getting End Time = REM =============================== set EndTime=%TIME% set EndHour=%EndTime:~0,2% set EndMin=%EndTime:~3,2% REM =============================== REM = Finding Difference = REM =============================== set /a Hour_Diff=EndHour - hour >nul set /a Min_Diff=EndMin - min >nul REM =============================== REM = Hour Hand Change? = REM =============================== IF [%Hour_Diff]==[0] ( Set Duration=%Min_Diff% ) ELSE ( Set /a Duration=60-%Min_Diff% >nul ) echo Start Time = %hour% : %min% echo End Time = %EndHour% : %EndMin% echo. echo Min Diff = %Min_Diff% echo. echo time difference (mins) = %Duration%
我也认为这是一个错字,但你确实希望在处理后设置endtime
。