繁体   English   中英

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

[英]How do I measure execution time of a command on the Windows command line?

是否有内置方法来测量 Windows 命令行上的命令执行时间?

PowerShell 有一个名为Measure-Command的 cmdlet。 您必须确保 PowerShell 在运行它的机器上可用。

PS> 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

Measure-Command捕获命令的 output。 您可以使用Out-Default将 output 重定向回您的控制台:

PS> Measure-Command { echo hi | Out-Default }
hi

Days              : 0
...

正如Makotoe评论的那样, Measure-Command返回一个TimeSpan object,因此测量的时间被打印为一堆字段。 您可以使用ToString()将 object 格式化为时间戳字符串:

PS> (Measure-Command { echo hi | Out-Default }).ToString()
hi
00:00:00.0001318

如果Measure-Command更改了控制台文本颜色,请使用[Console]::ResetColor()将其重置为正常。

如果你想

  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

如果你想做 output 重定向,你可以这样引用命令:

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

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

呵呵,最简单的解决办法可能是这样的:

echo %time%
YourApp.exe
echo %time%

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


如果应用程序使用控制台 output,将开始时间存储在临时变量中可能会很方便:

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

只是对 Casey.K 关于使用PowerShell中的Measure-Command的回答进行了一点扩展:

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

     powershell -Command "Measure-Command {echo hi}"
  2. 这会吃掉标准的 output,但你可以通过添加| Out-Default 来自 PowerShell | Out-Default如下:

     Measure-Command {echo hi | Out-Default}

    或者从命令提示符:

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

当然,您可以自由地将其包装在脚本文件*.ps1*.bat中。

如果您使用的是 Windows 2003(注意不支持 windows server 2008 及更高版本),您可以使用 Windows Server 2003 包含详细执行时间的资源包。 这是一个示例,对命令“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。 它无法从 Microsoft 下载中心直接下载,但仍然可以从archive.org - Windows Server 2003 Resource Kit Tools获得。

我在 Windows Server 2008 R2 中使用的单线是:

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

只要mycommand不需要引号(这与 cmd 的引号处理有关)。 /v:on允许独立评估两个不同的 TIME 值,而不是在执行命令时评估一次。

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

prompt $d $t $_$P$G

它给了你类似的东西:

23.03.2009 15:45:50,77

C:\>

如果您有一个执行命令的小批量脚本,请在每个命令之前留一个空行,例如

(空行)

我的命令

(下一个空行)

我的命令2.exe

您可以通过提示符中的时间信息来计算每个命令的执行时间。 最好的可能是将 pipe 和 output 转换为文本文件以进行进一步分析:

MyBatchFile.bat > output.txt

由于其他人建议安装免费软件和 PowerShell 之类的东西,因此您还可以安装Cygwin ,它可以让您访问许多基本的 Unix 命令,例如time

abe@abe-PC:~$ time sleep 5

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

不确定 Cygwin 增加了多少开销。

不如 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:

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

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

timer
yourapp.exe
timer /s

如果需要一组时间,只需将pipe、output的定时器/s写入一个.txt文件即可。

你可以在这里得到它: Gammadyne 的免费 DOS 实用程序


分辨率为 0.1 秒。

我使用的是 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

只要不超过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.

还有TimeMem (2012 年 3 月):

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

这里有一个

后缀计时器版本:

使用示例:

超时 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

^ - 基于“丹尼尔斯帕克斯”版本

根据您使用的 Windows 版本,只需运行bash进入 Bash 模式。 这将允许您直接使用 PowerShell 上不可用的一堆命令(如time命令)。 计时命令现在就像执行一样简单:

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

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

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

测量时间的替代方法是简单的“获取日期”。 转发 output 等就没有那么麻烦了。

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

Output:

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

这是一种避免延迟扩展的单行程序,这可能会干扰某些命令:

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

output 类似于:

 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"

output 看起来与此类似:

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

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

这是我的方法,没有转换也没有毫秒。 确定编码持续时间很有用(但仅限于 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

我的代码以毫秒为单位为您提供运行时间,最长为 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%来显示它。

如果其他人来这里寻找这个问题的答案,有一个 Windows API function 称为GetProcessTimes() 编写一个 C 小程序来启动命令、进行此调用并返回处理时间看起来并不需要太多工作。

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

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

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

是对 Luke Sampson 的漂亮timecmd.bat的评论/编辑并回复

出于某种原因,这只在整秒钟内给了我 output ......这对我来说没用。 我的意思是我运行 timecmd pause,它总是导致 1.00 秒、2.00 秒、4.00 秒……甚至 0.00 秒。 Windows 7: – Camilo Martin 2013 年 9 月 25 日 16:00"

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

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

添加 ',' 后, %time%毫秒在我的系统上工作

(*因为站点不允许匿名评论,并且即使我总是使用相同的访客 email 并结合 ipv6 ip 和浏览器指纹,也不能很好地跟踪身份,应该足以在没有密码的情况下唯一识别)

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

以下脚本仅使用“cmd.exe”并输出从创建管道到脚本之前的进程退出的毫秒数。 即,键入您的命令,然后 pipe 到脚本。 示例:“timeout 3 | runtime.cmd”应该产生类似“2990”的结果。 If you need both the runtime output and the stdin output, redirect stdin before the pipe - ex: "dir /s 1>temp.txt | runtime.cmd" would dump the output of the "dir" command to "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

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

根据 Luke Sampson 的说法,这个版本是八进制安全的,尽管任务应该在 24 小时内完成。

让 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;

一种使用纯 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 本地可用时有用

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

  • 同样的想法可以移植到 PowerShell

powershell 的另一种方法:

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

rem some commands

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

这将以毫秒为单位打印执行时间。

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

我在美国东部标准时间,报告的差异是 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

使用 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

具有区域格式、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

用法:
计时器& echo start_cmds & timeout /t 3 & echo end_cmds &计时器
计时器计时器“23:23:23,00”
计时器“23:23:23,00”和计时器
计时器“13.23.23,00”和计时器“03:03:03.00”
timer & timer "0:00:00.00" no & cmd /v:on /c echo until深夜=!timer_end!
现在可以混合输入,因为在执行期间那些不太可能但可能的时间格式更改

2:Function :定时器与批处理脚本捆绑在一起(示例用法如下):

@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 代表冒号结尾,点结尾和冒号集,点集 - 用于混合格式支持

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM