如何在Windows命令行上测量命令的执行时间?


Answers:


113

如果使用Windows 2003(请注意,不支持Windows Server 2008和更高版本),则可以使用Windows Server 2003资源工具包,其中包含显示详细执行状态的timeit.exe。这是一个示例,为命令“ timeit-?”计时:

C:\>timeit timeit -?
Invalid switch -?
Usage: TIMEIT [-f filename] [-a] [-c] [-i] [-d] [-s] [-t] [-k keyname | -r keyname] [-m mask] [commandline...]
where:        -f specifies the name of the database file where TIMEIT
                 keeps a history of previous timings.  Default is .\timeit.dat
              -k specifies the keyname to use for this timing run
              -r specifies the keyname to remove from the database.  If
                 keyname is followed by a comma and a number then it will
                 remove the slowest (positive number) or fastest (negative)
                 times for that keyname.
              -a specifies that timeit should display average of all timings
                 for the specified key.
              -i specifies to ignore non-zero return codes from program
              -d specifies to show detail for average
              -s specifies to suppress system wide counters
              -t specifies to tabular output
              -c specifies to force a resort of the data base
              -m specifies the processor affinity mask

Version Number:   Windows NT 5.2 (Build 3790)
Exit Time:        7:38 am, Wednesday, April 15 2009
Elapsed Time:     0:00:00.000
Process Time:     0:00:00.015
System Calls:     731
Context Switches: 299
Page Faults:      515
Bytes Read:       0
Bytes Written:    0
Bytes Other:      298

您可以在Windows 2003资源工具包中获得TimeIt。在这里下载 。


7
该套件在Windows 2008 64bit上有问题,在2008 R2上不起作用
Artem

有什么方法可以测量内核时间和/或产生的子进程使用的时间吗?
rogerdpack 2011年

38
仅供参考-我认为timeit在Windows 7 64位系统上不起作用。你的错误措施命令‘像Casey.K提示:“无法查询系统的性能数据(c0000004)相反,使用PowerShell的。’ stackoverflow.com/questions/673523/...
迈克尔·拉Vo1E时

6
在Windows 7中,我看到“'timeit'未被识别为内部或外部命令,可操作程序或批处理文件”。
Panic Panic 2013年

3
我在Windows 10中看不到该命令,也无法轻松找到Win 10的资源工具包。有人知道如何在10中获得此工具吗?
杰伊·伊曼

469

另外,Windows PowerShell具有类似于Bash的“ time”命令的内置命令。它称为“测量命令”。您必须确保在运行PowerShell的计算机上安装了PowerShell。

输入示例:

Measure-Command {echo hi}

示例输出:

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 0
Ticks             : 1318
TotalDays         : 1.52546296296296E-09
TotalHours        : 3.66111111111111E-08
TotalMinutes      : 2.19666666666667E-06
TotalSeconds      : 0.0001318
TotalMilliseconds : 0.1318

21
这是Windows 7用户的最佳解决方案,因为timeit.exe似乎不支持Windows 7
Michael La Voie

14
如果要使用内部dos命令(例如:dir,echo,del等),请不要忘记插入“ cmd / c”:Measure-Command {cmd / c dir / sc:\ windows> nul}
LietKynes 2012年

7
如果您要.exe在当前目录中对进行基准测试,请使用以下命令:Measure-Command { .\your.exe }pwd除非明确告知,否则PowerShell显然不会运行。
Cristian Diaconescu 2013年

13
令人讨厌的是它隐藏了标准输出。
Zitrax

13
这是不是在所有的工具“类似bash的时间命令”。很高兴知道...但是:它不执行并返回<stdout>大括号中命令的结果!
Kurt Pfeifle 2015年

286

如果你想

  1. 以(hh:mm:ss.ff格式)测量执行时间,精确到百分之一秒
  2. 不必下载和安装资源包
  3. 看起来像个巨大的DOS书呆子(没有)

尝试将以下脚本复制到新的批处理文件中(例如timecmd.bat):

@echo off
@setlocal

set start=%time%

:: Runs your command
cmd /c %*

set end=%time%
set options="tokens=1-4 delims=:.,"
for /f %options% %%a in ("%start%") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in ("%end%") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 100

set /a hours=%end_h%-%start_h%
set /a mins=%end_m%-%start_m%
set /a secs=%end_s%-%start_s%
set /a ms=%end_ms%-%start_ms%
if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms%
if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs%
if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins%
if %hours% lss 0 set /a hours = 24%hours%
if 1%ms% lss 100 set ms=0%ms%

:: Mission accomplished
set /a totalsecs = %hours%*3600 + %mins%*60 + %secs%
echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total)

用法

如果将timecmd.bat放在路径中的目录中,则可以从以下任何位置调用它:

timecmd [your command]

例如

C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18

如果要进行输出重定向,可以引用以下命令:

timecmd "dir c:\windows /s > nul"

这应该处理从午夜之前到午夜之后运行的命令,但是如果您的命令运行24小时或更长时间,则输出将是错误的。


9
除非您的命令是另一个批处理文件,否则用%*替换cmd / c%*是可行的。然后,您必须做timecmd呼叫other.bat
Jesse Chisholm

2
@JesseChisholm在Windows 8中(我也已经在Windows 7中阅读过),您不需要调用.bat
Brian J

4
出于某种原因,这只会给我整整一秒的输出...对我来说这是没有用的。我的意思是说我跑步了timecmd pause,它总是导致1.00秒,2.00秒,4.00秒...甚至0.00秒!Windows 7
Camilo Martin

9
@CamiloMartin和其他拥有此功能的人(例如我)-您可能有一个语言环境,该语言环境使用COMMA而不是DOT来表示小数。因此,在此脚本中,将其更改delims=:.delims=:.,,然后它应该“全面运行”。
Tomasz Gandor 2014年

5
该脚本中存在严重的算术错误:尝试使用: set start=10:10:10.10 set end=10:11:10.09它会输出: command took 0:1:-1.99 (59.99s total) 您应该颠倒进行“ lss 0”比较的4行的顺序,以便使进位正确地从低六进制数字提高到高六进制数字。然后输出变为: command took 0:0:59.99 (59.99s total)
让弗朗索瓦Larvoire

230

呵呵,最简单的解决方案可能是这样的:

echo %time%
YourApp.exe
echo %time%

这适用于开箱即用的每个Windows。


对于使用控制台输出的应用程序,将开始时间存储在一个临时变量中可能会很方便:

set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%

163
你疯了吗?!这涉及到在大脑中进行数学运算。这就是我们发明计算机的原因,因此我们可以避免做类似的事情。
卢克·桑普森

1
辉煌!即使如此,对于CPU时间并没有真正的帮助
Elijah Saounkine 2011年

10
更好的是(如果您的应用将输出吐到控制台上):(set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time% 对不起,在评论中找不到换行符)
Jono 2012年

1
@LukeSampson,您可以set用来做数学。;-)哦,等等,没关系,您已经在下面完成了。
Synetech

2
不,这是一个不好的选择。这告诉您时钟时间,而不是CPU时间。因此,即使您的命令行可能只花费100毫秒,但是如果有另一个应用程序占用CPU,您的应用程序也可能需要几秒钟(减少100倍或更多)。实际上,如果您的计算机运行缓慢,您甚至可以等待一分钟,以运行100ms的小应用程序。跟踪CPU时间,而不是挂钟时间!
Ryan Shillington 2014年

102

只是一点点扩大,从Casey.K回答有关使用Measure-CommandPowerShell的

  1. 您可以从标准命令提示符处调用PowerShell,如下所示:

    powershell -Command "Measure-Command {echo hi}"
    
  2. 这将吃掉标准输出,但是您可以通过| Out-Default从PowerShell中添加以下内容来避免这种情况:

    Measure-Command {echo hi | Out-Default}
    

    或在命令提示符下:

    powershell -Command "Measure-Command {echo hi | Out-Default}"
    

当然,您可以随意将其包装在脚本文件*.ps1或中*.bat


1
如果我们要测量的命令带有引号怎么办?在这种情况下可以将其转换为.bat脚本吗?例如measureTime.bat "c:\program files\some dir\program.exe"
GetFree

53

我在Windows Server 2008 R2中使用的单行代码是:

cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"

只要mycommand不需要引号(使用cmd的引号处理即可)。的/v:on是,以允许两个不同的时间值进行独立评估,而不是一次,在命令的执行。


这也不适用于“垃圾邮件”批处理,该批处理将覆盖第一次标签,并暗示您替换计算机进行计算,如stackoverflow.com/questions/673523/…所示
2013年

通常,您可以^使用cmd来^"
排除

2
如果您第二次重复执行cmd / v:on,我们甚至可以让mycommand包含引号。范例:cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
Maarten Pennings 2015年

8
更简单:echo %time% & *mycommand* & call echo %^time%。另请参阅此答案
阿西尼(Aacini)

如果您的命令输出过多,则将两个时间放在一起可能会更容易:cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
ZHANG Zikai

49

如果打开命令窗口并手动调用命令,则可以在每个提示上显示时间戳,例如

prompt $d $t $_$P$G

它给你类似的东西:

23.03.2009 15:45:50,77

C:\>

如果您有一个小的批处理脚本来执行命令,则在每个命令前都留一个空行,例如

(空行)

myCommand.exe

(下一行)

myCommand2.exe

您可以通过提示符中的时间信息来计算每个命令的执行时间。最好的办法可能是将输出传递到文本文件以进行进一步分析:

MyBatchFile.bat > output.txt

3
我以为我会在讨论后的几​​年内发言,以感谢您分享提示命令。我已经看到了许多CMD技巧(更多的是bash家伙),但这使我不知所措。
史蒂夫·霍华德

简单,优雅,无需安装,也无需为一个命令编写批处理文件,并且可以将批处理文件中的每个步骤计时。
Matt

26

由于其他人建议安装免费软件和PowerShell等内容,因此您也可以安装Cygwin,这将使您可以访问许多基本的Unix命令,例如time

abe@abe-PC:~$ time sleep 5

real    0m5.012s
user    0m0.000s
sys 0m0.000s

不知道Cygwin会增加多少开销。


41
在回答Windows问题时,Cygwin被视为作弊:-)
mivk 2011年

14
他已规定ResourceKit,TimeMem,ptime.exe,PowerShell和其他实用程序用户首先开始作弊。因此,在撰写之前,作者已经使您的评论不合适。
2013年

自从我发现它是最简单的解决方案以来,我也对此表示赞同,因为免费程序Cmder包括bash!cmder.net请记住,如果需要在bash中转义空格,请在空格前使用黑斜杠\,而不要使用“引号”。例如cd / c / Program \ Files /
lukescammell

24

不像Unix上的某些功能那么优雅,但是创建一个如下的cmd文件:

@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T

这样将显示开始和停止时间,如下所示:

The current time is: 10:31:57.92
Enter the new time:
The current time is: 10:32:05.94
Enter the new time:

2
假设您不需要跨不同语言的可移植性,则还可以在“ time <nul”(顺便说一下nul的用法;我一直使用echo。| time)之后放置一个findstr“ current”或类似的东西。看起来不那么优雅:))。并使用“ for”仅提取时间,而不提取文本。
乔伊,

2
如果启用了命令扩展(即默认设置),的Win XP的版本time/t它只是显示当前系统时间,不提示您输入一个新的时间选项。但是,当您这样做时,它仅显示小时和分钟,对于某些用法来说可能不够好。(请参阅John Snow对这个问题的回答。)
martineau 2011年

3
time /T仅在过程运行几分钟后才可用!time < nul较丑但较精确。
PhiLho 2013年

6
您也可以使用echo %time%它提供与相同的格式和精度time < nul,但是避免Enter the new time:输出...
aschipfl


19

我使用称为“ GS Timer”的免费软件。

只需像这样制作一个批处理文件:

timer
yourapp.exe
timer /s

如果需要一组时间,只需将timer / s的输出通过管道传输到.txt文件中。

您可以在此处获得:Gammadyne的免费DOS实用程序


分辨率为0.1秒。


4
我认为使用第三方应用程序不应被视为“以标准方式”进行。
martineau 2011年

4
发问者的意思是“无需安装其他软件”,但是最重要的(接受的)答案还需要安装整个Windows 2003 Resource Kit!无论如何,timer.exe非常适合我想要的东西,谢谢!
雨果

1
这是一个植入的链接。SoftPedia是一个单击场。
Tom

@Tom请解释,您是什么意思“植入链接”?
pepoluan 2012年

10
这是开发人员自己页面的直接链接:gammadyne.com/cmdline.htm#timer
Hugo

14

我使用的是Windows XP,由于某种原因timeit.exe对我不起作用。我找到了另一种选择-PTIME。这很好。

http://www.pc-tools.net/win32/ptime/

范例-

C:\> ptime

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>

Syntax: ptime command [arguments ...]

ptime will run the specified command and measure the execution time
(run time) in seconds, accurate to 5 millisecond or better. It is an
automatic process timer, or program timer.


C:\> ptime cd

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>

===  cd ===
C:\

Execution time: 0.015 s

在Windows 8.1上也能很好地工作。我将我的名字重命名为timer.exe,因为我永远不记得ptime的名字。
Brian Burns

11

还有 TimeMem(2012年3月):

这是一个Windows实用程序,用于执行程序并显示其执行时间,内存使用情况和IO统计信息。它的功能类似于Unix时间实用程序。


10

只要不超过24小时...

@echo off

set starttime=%TIME%
set startcsec=%STARTTIME:~9,2%
set startsecs=%STARTTIME:~6,2%
set startmins=%STARTTIME:~3,2%
set starthour=%STARTTIME:~0,2%
set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%)

:TimeThis
ping localhost 

set endtime=%time%
set endcsec=%endTIME:~9,2%
set endsecs=%endTIME:~6,2%
set endmins=%endTIME:~3,2%
set endhour=%endTIME:~0,2%
if %endhour% LSS %starthour% set /a endhour+=24
set /a endtime=(%endhour%*60*60*100)+(%endmins%*60*100)+(%endsecs%*100)+(%endcsec%)

set /a timetaken= ( %endtime% - %starttime% )
set /a timetakens= %timetaken% / 100
set timetaken=%timetakens%.%timetaken:~-2%

echo.
echo Took: %timetaken% sec.

5
令人印象深刻,但是如果开始时间或结束时间为08或09,则我认为它不起作用,因为它们被解释为八进制。我的回答是这样的:)
卢克·桑普森

6

这里有一个

Postfix计时器版本:

用法示例:

超时1 | TimeIt.cmd

Execution took  ~969 milliseconds.

将其复制并粘贴到某些编辑器(例如Notepad ++)中,并将其另存为TimeIt.cmd

:: --- TimeIt.cmd ----
    @echo off
    setlocal enabledelayedexpansion

    call :ShowHelp

    :: Set pipeline initialization time
    set t1=%time%

    :: Wait for stdin
    more

    :: Set time at which stdin was ready
    set t2=!time!


    :: Calculate difference
    Call :GetMSeconds Tms1 t1
    Call :GetMSeconds Tms2 t2

    set /a deltaMSecs=%Tms2%-%Tms1%
    echo Execution took ~ %deltaMSecs% milliseconds.

    endlocal
goto :eof

:GetMSeconds
    Call :Parse        TimeAsArgs %2
    Call :CalcMSeconds %1 %TimeAsArgs%

goto :eof

:CalcMSeconds
    set /a %1= (%2 * 3600*1000) + (%3 * 60*1000) + (%4 * 1000) + (%5)
goto :eof

:Parse

    :: Mask time like " 0:23:29,12"
    set %1=!%2: 0=0!

    :: Replace time separators with " "
    set %1=!%1::= !
    set %1=!%1:.= !
    set %1=!%1:,= !

    :: Delete leading zero - so it'll not parsed as octal later
    set %1=!%1: 0= !
goto :eof

:ShowHelp
    echo %~n0 V1.0 [Dez 2015]
    echo.
    echo Usage: ^<Command^> ^| %~nx0
    echo.
    echo Wait for pipe getting ready... :)
    echo  (Press Ctrl+Z ^<Enter^> to Cancel)
goto :eof

^-基于“ Daniel Sparks”版本


5

测量时间的另一种选择就是“获取日期”。您不必担心转发输出等问题。

$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start

输出:

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 506
Ticks             : 15060003
TotalDays         : 1.74305590277778E-05
TotalHours        : 0.000418333416666667
TotalMinutes      : 0.025100005
TotalSeconds      : 1.5060003
TotalMilliseconds : 1506.0003

这对我来说是完美的
Brett Rowberry

4

这是一个单行代码,可避免延迟扩展,这可能会干扰某些命令:

cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "

输出类似于:

14:30:27.58$
...
14:32:43.17$ rem/ 

对于长期试验代替$T通过$D, $T%TIME%通过%DATE%, %TIME%包括日期。

要在批处理文件中使用此文件,请替换%Z%%Z


更新资料

这是一种改进的单线(也没有延迟的扩展):

cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"

输出看起来像这样:

2015/09/01, 14:30:27.58$ rem/ 
...
2015/09/01, 14:32:43.17$ prompt

该方法不包括cmd在结果中实例化新内容的过程,也不包括prompt命令。


4

根据您使用的Windows版本,仅运行它就bash会使您进入Bash模式。这将使您可以使用直接在PowerShell上不可用的一堆命令(如time命令)。现在,定时命令就像执行一样容易:

# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>

注意:通过exit在Bash模式下运行,您可以轻松地从Bash模式退出并返回到主流Shell 。

在尝试了Measure-Command有时会产生不希望的统计数据的其他方法(例如)之后,这对我来说非常适用(Windows 10)。希望这也对您有用。


2
作为Windows 10 1607的最佳答案。
CarpeDiemKopi

2

如果其他任何人都来这里寻找该问题的答案,则有一个Windows API函数称为GetProcessTimes()。编写一个小的C程序来启动命令,进行此调用并返回处理时间似乎并没有太多的工作。


3
下载一个小的C程序来启动命令,进行此调用(以及进行更多的高级测量)并返回处理时间,似乎并没有太多的工作。
Elazar Leibovich

@ElazarLeibovich powershell吗?您可以从C#调用它。
KeyWeeUsr


2

是对卢克·桑普森的好话的评论/编辑,timecmd.bat并回复了

出于某种原因,这只会给我整整几秒钟的输出...对我而言这是没有用的。我的意思是我运行timecmd暂停,它总是导致1.00秒,2.00秒,4.00秒...甚至0.00秒!Windows7。– Camilo Martin 2013年9月25日16:00“

在某些配置中,定界符可能有所不同。以下更改应涵盖至少大多数西方国家。

set options="tokens=1-4 delims=:,." (added comma)

%time%毫秒我的系统上运行补充说后“”

(*因为站点不允许匿名注释,并且即使我始终使用相同的来宾电子邮件(结合ipv6 ip和浏览器指纹也应足以无需密码唯一标识),也无法很好地跟踪身份)


我只是在向下滚动到您的答案之前发表了评论。无论如何,卢克的脚本可以零垫小时,分钟和秒,而不仅仅是亚秒(这是厘秒,而不是毫秒,BTW)。参见此处:en.wiktionary.org/wiki/centisecond
Tomasz Gandor 2014年

2

这是我的方法,没有转换,也没有毫秒。确定编码持续时间(但限制为24小时)非常有用:

@echo off

:start
REM Start time storage
set ST=%time%
echo Process started at %ST%
echo.
echo.

REM Your commands
REM Your commands
REM Your commands

:end
REM Start Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%ST%") do set /a h1=%%a & set /a m1=%%b & set /a s1=%%c

REM End Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%TIME%") do set /a h2=%%a & set /a m2=%%b & set /a s2=%%c

REM Difference
set /a h3=%h2%-%h1% & set /a m3=%m2%-%m1% & set /a s3=%s2%-%s1%

REM Time Adjustment
if %h3% LSS 0 set /a h3=%h3%+24
if %m3% LSS 0 set /a m3=%m3%+60 & set /a h3=%h3%-1
if %s3% LSS 0 set /a s3=%s3%+60 & set /a m3=%m3%-1

echo Start    :    %ST%
echo End    :    %time%
echo.
echo Total    :    %h3%:%m3%:%s3%
echo.
pause

1
@echo off & setlocal

set start=%time%

REM Do stuff to be timed here.
REM Alternatively, uncomment the line below to be able to
REM pass in the command to be timed when running this script.
REM cmd /c %*

set end=%time%

REM Calculate time taken in seconds, to the hundredth of a second.
REM Assumes start time and end time will be on the same day.

set options="tokens=1-4 delims=:."

for /f %options% %%a in ("%start%") do (
    set /a start_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
    set /a start_hs=100%%d %% 100
)

for /f %options% %%a in ("%end%") do (
    set /a end_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
    set /a end_hs=100%%d %% 100
)

set /a s=%end_s%-%start_s%
set /a hs=%end_hs%-%start_hs%

if %hs% lss 0 (
    set /a s=%s%-1
    set /a hs=100%hs%
)
if 1%hs% lss 100 set hs=0%hs%

echo.
echo  Time taken: %s%.%hs% secs
echo.

不起作用。得到:括号不平衡。括号不平衡。缺少操作数。
理查德·桑多兹

@RichardSandoz它工作正常,没有不平衡的括号。您如何使用它?
MikeM '16

1

以下脚本仅使用“ cmd.exe”,并输出从创建管道到脚本之前的进程退出之间的毫秒数。即,键入您的命令,并将其通过管道传递到脚本。示例:“超时3 | runtime.cmd”应产生类似“ 2990”的信息。如果同时需要运行时输出和stdin输出,请在管道之前重定向stdin-例如:“ dir / s 1> temp.txt | runtime.cmd”会将“ dir”命令的输出转储到“ temp.txt”并将运行时打印到控制台。

:: --- runtime.cmd ----
@echo off
setlocal enabledelayedexpansion

:: find target for recursive calls
if not "%1"=="" (
    shift /1
    goto :%1
    exit /b
)

:: set pipeline initialization time
set t1=%time%

:: wait for stdin
more > nul

:: set time at which stdin was ready
set t2=!time!

::parse t1
set t1=!t1::= !
set t1=!t1:.= !
set t1=!t1: 0= !

:: parse t2
set t2=!t2::= !
set t2=!t2:.= !
set t2=!t2: 0= !

:: calc difference
pushd %~dp0
for /f %%i in ('%0 calc !t1!') do for /f %%j in ('%0 calc !t2!') do (
    set /a t=%%j-%%i
    echo !t!
)
popd
exit /b
goto :eof

:calc
set /a t=(%1*(3600*1000))+(%2*(60*1000))+(%3*1000)+(%4)
echo !t!
goto :eof

endlocal

好吧,与其递归地调用脚本,不如考虑这样做call :calc。我是在这里做的。链接代码通过这种方式变得更好。:D
纳杜语

错误1 将在第12小时失败。示例:“ 0:23:19,42” 错误#2 如果小数点不是,将失败。同样的例子:“零时23分十九秒 42”,这里小数点,<__________>嘛试图编辑但是那个傻小子****在“编辑委员会批准”拒绝它- 5 3投“此编辑也发生了变化很多作者的初衷。” 因此,如果想尝试进行运气编辑或仅保留错误,则“作者的原始意图保持不变”。facepalm
Nadu

当时钟的分辨率几乎无法达到1/100秒的分辨率时,无法输出毫秒。
jwdonahue

1

driblio的答案可以短一些(尽管可读性不强)

@echo off

:: Calculate the start timestamp
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _started=_hours*60*60*100+_min*60*100+_sec*100+_cs


:: yourCommandHere


:: Calculate the difference in cSeconds
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _duration=_hours*60*60*100+_min*60*100+_sec*100+_cs-_started

:: Populate variables for rendering (100+ needed for padding)
set /a _hours=_duration/60/60/100,_min=100+_duration/60/100%%60,_sec=100+(_duration/100%%60%%60),_cs=100+_duration%%100

echo Done at: %_time% took : %_hours%:%_min:~-2%:%_sec:~-2%.%_cs:~-2%

::prints something like:
::Done at: 12:37:53,70 took: 0:02:03.55

此言卢克桑普森的这个版本是八进制安全,虽然任务应在24小时内完成。


不起作用。一位数字小时缺少运算符。
理查德·桑多兹

set _time=%time: =0%解决了个位数小时的问题-在两个地方都替换。
劳尔

1
  1. 在程序所在的目录中,键入notepad mytimer.bat,单击“是”以创建一个新文件。

  2. 粘贴下面的代码,替换YourApp.exe为您的程序,然后保存。

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
  3. mytimer.bat在命令行中键入,然后按Enter。


7
时间/ t只给您时间为HH:MM。为了给可执行文件计时,您通常需要更高的准确性...您可以设置几分之一秒的时间吗?我测试了JohnW的解决方案(时间<nul),实际上将时间降低到1 / 100s:HH:MM:SS.XX
敬畏

1

我的代码为您提供了以毫秒为单位的运行时间(最多24小时),它不受区域设置的影响,并且如果代码运行至午夜,则将为负值。它使用延迟扩展,应保存在cmd / bat文件中。

在您的代码之前:

SETLOCAL EnableDelayedExpansion

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t1 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t1=!t1!%t:~15,3%

在您的代码之后:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t2 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t2=!t2!%t:~15,3%
set /a t2-=t1 && if !t2! lss 0 set /a t2+=24*3600000

如果要以HH:mm:ss.000格式运行时间,请添加:

set /a "h=t2/3600000,t2%%=3600000,m=t2/60000,t2%%=60000" && set t2=00000!t2!&& set t2=!t2:~-5!
if %h% leq 9 (set h=0%h%) && if %m% leq 9 (set m=0%m%)
set t2=%h%:%m%:%t2:~0,2%.%t2:~2,3%

ENDLOCAL

变量t2保存您的运行时间,您可以echo %t2%显示它。


1

Perl安装了可用的招聘解决方案后,运行:

C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result

STDERR在测量秒数之前

#!/usr/bin/perl -w

use Time::HiRes qw();
my $T0 = [ Time::HiRes::gettimeofday ];

my $stdout = `@ARGV`;

my $time_elapsed = Time::HiRes::tv_interval( $T0 );

print $time_elapsed, "\n";
print $stdout;

0

使用sub返回时间(以百分之一秒为单位)

::tiemeit.cmd
@echo off
Setlocal EnableDelayedExpansion

call :clock 

::call your_command  or more > null to pipe this batch after your_command

call :clock

echo %timed%
pause
goto:eof

:clock
if not defined timed set timed=0
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( 
set /A timed = "(((1%%a - 100) * 60 + (1%%b - 100)) * 60 + (1%%c - 100))  * 100 + (1%%d - 100)- %timed%"
)
goto:eof

0

具有区域格式,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”否&cmd / v:on / c回显直到午夜=!timer_end!
现在可以混合输入,以应对那些不太可能但可能在执行期间更改时间格式的情况

2:与批处理脚本捆绑在一起的Function :timer(下面的示例用法):

@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

CE,DE和CS,DS代表冒号,点尾和冒号集,点集-用于混合格式支持


0

以下脚本模拟* nix纪元时间,但它是本地和区域性的。它应该处理包括leap年在内的压光机边缘情况。如果可以使用Cygwin,则可以通过指定Cygwin来比较历元值选项。

我在美国东部标准时间(EST),报告的差异是4个小时,相对来说是正确的。有一些有趣的解决方案可以消除TZ和区域依赖关系,但是我发现这并不是一件小事。

@ECHO off
SETLOCAL EnableDelayedExpansion

::
::  Emulates local epoch seconds
::

:: Call passing local date and time
CALL :SECONDS "%DATE%" "%TIME%"
IF !SECONDS! LEQ 0 GOTO END

:: Not testing - print and exit
IF NOT "%~1"=="cygwin" (
    ECHO !SECONDS!
    GOTO END
)

:: Call on Cygwin to get epoch time
FOR /F %%c IN ('C:\cygwin\bin\date +%%s') DO SET EPOCH=%%c

:: Show the results
ECHO Local Seconds: !SECONDS!
ECHO Epoch Seconds: !EPOCH!

:: Calculate difference between script and Cygwin
SET /A HOURS=(!EPOCH!-!SECONDS!)/3600
SET /A FRAC=(!EPOCH!-!SECONDS!)%%3600

:: Delta hours shown reflect TZ
ECHO Delta Hours: !HOURS! Remainder: !FRAC!

GOTO END

:SECONDS
SETLOCAL  EnableDelayedExpansion

    :: Expecting values from caller
    SET DATE=%~1
    SET TIME=%~2

    :: Emulate Unix epoch time without considering TZ
    SET "SINCE_YEAR=1970"

    :: Regional constraint! Expecting date and time in the following formats:
    ::   Sun 03/08/2015   Day MM/DD/YYYY
    ::   20:04:53.64         HH:MM:SS
    SET VALID_DATE=0
    ECHO !DATE! | FINDSTR /R /C:"^... [0-9 ][0-9]/[0-9 ][0-9]/[0-9][0-9][0-9][0-9]" > nul && SET VALID_DATE=1
    SET VALID_TIME=0
    ECHO !TIME! | FINDSTR /R /C:"^[0-9 ][0-9]:[0-9 ][0-9]:[0-9 ][0-9]" > nul && SET VALID_TIME=1
    IF NOT "!VALID_DATE!!VALID_TIME!"=="11" (
        IF !VALID_DATE! EQU 0  ECHO Unsupported Date value: !DATE! 1>&2
        IF !VALID_TIME! EQU 0  ECHO Unsupported Time value: !TIME! 1>&2
        SET SECONDS=0
        GOTO SECONDS_END
    )

    :: Parse values
    SET "YYYY=!DATE:~10,4!"
    SET "MM=!DATE:~4,2!"
    SET "DD=!DATE:~7,2!"
    SET "HH=!TIME:~0,2!"
    SET "NN=!TIME:~3,2!"
    SET "SS=!TIME:~6,2!"
    SET /A YEARS=!YYYY!-!SINCE_YEAR!
    SET /A DAYS=!YEARS!*365

    :: Bump year if after February  - want leading zeroes for this test
    IF "!MM!!DD!" GEQ "0301" SET /A YEARS+=1

    :: Remove leading zeros that can cause octet probs for SET /A
    FOR %%r IN (MM,DD,HH,NN,SS) DO (
        SET "v=%%r"
        SET "t=!%%r!"
        SET /A N=!t:~0,1!0
        IF 0 EQU !N! SET "!v!=!t:~1!"
    )

    :: Increase days according to number of leap years
    SET /A DAYS+=(!YEARS!+3)/4-(!SINCE_YEAR!%%4+3)/4

    :: Increase days by preceding months of current year
    FOR %%n IN (31:1,28:2,31:3,30:4,31:5,30:6,31:7,31:8,30:9,31:10,30:11) DO (
        SET "n=%%n"
        IF !MM! GTR !n:~3! SET /A DAYS+=!n:~0,2!
    )

    :: Multiply and add it all together
    SET /A SECONDS=(!DAYS!+!DD!-1)*86400+!HH!*3600+!NN!*60+!SS!

:SECONDS_END
ENDLOCAL & SET "SECONDS=%SECONDS%"
GOTO :EOF

:END
ENDLOCAL

对下降投票感到好奇。谢谢。
bvj

0

一种使用纯PHP的cmd和一个环境的解决方案。变量:

@echo off
setlocal enableextensions

REM set start time env var
FOR /F "tokens=* USEBACKQ" %%F IN (`php -r "echo microtime(true);"`) DO ( SET start_time=%%F )

## PUT_HERE_THE_COMMAND_TO_RUN ##

REM echo elapsed time
php -r "echo 'elapsed: ' . (round(microtime(true) - trim(getenv('start_time')), 2)) . ' seconds' . mb_convert_encoding('&#13;&#10;', 'UTF-8', 'HTML-ENTITIES');"
  • 不需要cygwin或不受信任的实用程序。PHP在本地可用时有用

  • 精度和输出格式可以轻松调整

  • 可以为PowerShell移植相同的想法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.