关于批处理文件:如何在Windows命令行上测量命令的执行时间?

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

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


或者,WindowsPowerShell有一个类似于bash的"time"命令的内置命令。它被称为"measure命令"。您必须确保在运行它的计算机上安装了PowerShell。

实例输入:

1
Measure-Command {echo hi}

实例输出:

1
2
3
4
5
6
7
8
9
10
11
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


如果你想要

  • 以(hh:mm:ss.ff格式)测量到百分之一秒的执行时间
  • 无需下载和安装资源包
  • 看起来像一个巨大的DOS书呆子(谁没有)
  • 尝试将以下脚本复制到新的批处理文件(例如timeCmd.bat)中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    @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放在路径中的目录中,则可以从以下任何位置调用它:

    1
    timecmd [your command]

    例如。

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

    如果要执行输出重定向,可以这样引用命令:

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

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


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

    1
    2
    3
    echo %time%
    YourApp.exe
    echo %time%

    它适用于所有开箱即用的窗口。


    对于使用控制台输出的应用程序,可以方便地将启动时间存储在临时变量中:

    1
    2
    3
    4
    set startTime=%time%
    YourApp.exe
    echo Start Time: %startTime%
    echo Finish Time: %time%


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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。下载它在这里。


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

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

    1
    powershell -Command"Measure-Command {echo hi}"
  • 这将占用标准输出,但您可以通过从PowerShell中添加这样的EDOCX1[3]来防止这种情况:

    1
    Measure-Command {echo hi | Out-Default}

    或从命令提示:

    1
    powershell -Command"Measure-Command {echo hi | Out-Default}"
  • 当然,您可以将其包装在脚本文件*.ps1*.bat中。


    我在Windows Server 2008 R2中使用的一行程序是:

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

    只要mycommand不需要引号(哪个螺钉带有cmd的引号处理)。/v:on允许对两个不同的时间值进行独立评估,而不是在执行命令时进行一次评估。


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

    1
    prompt $d $t $_$P$G

    它给你的感觉是:

    23.03.2009 15:45:50,77

    C:\>

    如果您有一个执行命令的小批处理脚本,那么在每个命令之前都有一个空行,例如。

    (empty line)

    myCommand.exe

    (next empty line)

    myCommand2.exe

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

    1
    MyBatchFile.bat > output.txt


    由于其他人建议安装免费软件和PowerShell,您也可以安装cygwin,这样您就可以访问许多基本的UNIX命令,如time:

    1
    2
    3
    4
    5
    abe@abe-PC:~$ time sleep 5

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

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


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

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

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

    1
    2
    3
    4
    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定时器"的免费软件。

    只需制作这样的批处理文件:

    1
    2
    3
    timer
    yourapp.exe
    timer /s

    如果您需要一组时间,只需将timer/s的输出导入一个.txt文件。

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

    分辨率为0.1秒。


    我使用的是Windows XP,出于某种原因,Timeit.exe不适合我。我找到了另一个选择——提姆。这很管用。

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

    示例-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    C:\> ptime

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

    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 <[email protected]>

    ===  cd ===
    C:\

    Execution time: 0.015 s


    只要不超过24小时…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    @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月):

    This is a Windows utility which executes a program and displays its
    execution time, memory usage, and IO statistics. It is similar in
    functionality to the Unix time utility.


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

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

    输出类似于:

    1
    2
    3
    14:30:27.58$
    ...
    14:32:43.17$ rem/

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

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

    更新

    这里有一个改进的单衬层(没有延迟膨胀):

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

    输出与此类似:

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

    这种方法不包括在结果中建立新的cmd的过程,也不包括prompt命令。


    这里是一个

    后缀计时器版本:

    使用实例:

    超时1 timeit.cmd

    1
    Execution took  ~969 milliseconds.

    复制并粘贴到一些编辑器中,例如记事本+,然后将其另存为timeit.cmd:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    :: --- 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"版本


    测量时间的另一种方法就是简单地"获取日期"。在转发输出等方面,您没有那么麻烦。

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

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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


    这是对卢克·桑普森的《可爱的爱德华》的评论/编辑,并回复

    For some reason this only gives me output in whole seconds... which for me is useless. I mean that I run timecmd pause, and it always results in 1.00 sec, 2.00 sec, 4.00 sec... even 0.00 sec! Windows 7. – Camilo Martin Sep 25 '13 at 16:00 "

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

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

    在添加了","之后,%time%毫秒在我的系统上工作。

    (*因为网站不允许匿名评论,也不保持良好的身份记录,即使我总是使用相同的访客电子邮件,与IPv6 IP和浏览器指纹相结合,应该足以在没有密码的情况下进行唯一标识)


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


  • 在程序所在的目录中,键入notepad mytimer.bat,单击"是"创建新文件。

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

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


  • 以下脚本仅使用"cmd.exe",并输出从创建管道到脚本前的进程退出的毫秒数。例如,键入命令,并通过管道将发送到脚本。示例:"timeout 3 runtime.cmd"应生成类似"2990"的结果。如果需要运行时输出和stdin输出,请将stdin重定向到管道之前-例如:"dir/s 1>temp.txt runtime.cmd"将"dir"命令的输出转储到"temp.txt",并将运行时打印到控制台。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    :: --- 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的答案可以缩短一点(虽然可读性不强)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @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小时内完成。


    我的代码以毫秒为单位提供运行时间,最长24小时,它不区分区域设置,并且如果代码运行到午夜,则说明负值。它使用延迟的扩展,应该保存在一个cmd/bat文件中。

    在您的代码之前:

    1
    2
    3
    4
    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%

    代码之后:

    1
    2
    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格式运行时间,请添加:

    1
    2
    3
    4
    5
    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版本的不同,运行bash将使您进入bash模式。这将允许您使用PowerShell上不直接可用的一系列命令(如time命令)。现在,命令的计时与执行一样简单:

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

    Note: You can easily quit from Bash mode and return back into your mainstream shell by running exit while in Bash mode.

    在尝试了其他方法(如Measure-Command)之后,这对我(Windows10)非常有效,因为这些方法有时会产生不需要的统计数据。希望这对你也有用。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    @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.


    如果Perl安装了Hires解决方案,请运行:

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

    stderr在测量秒之前

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/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,"
    ";
    print $stdout;

    下面的脚本模拟*尼克斯时代,但它是本地和区域的。它应该处理包括闰年在内的压延机边缘情况。如果cygwin可用,则可以通过指定cygwin选项来比较epoch值。

    我在EST,报告的差异是4小时,这是相对正确的。有一些有趣的解决方案可以消除TZ和区域依赖关系,但没有什么我注意到的微不足道的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    @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


    以下是我的方法,没有转换,也没有毫秒。确定编码持续时间(仅限于24小时)很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @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

    使用Sub返回以百分之一秒为单位的时间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ::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%或当前目录的某个位置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @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_-comms&timeout/t 3&echo end_-comms&timer计时器和计时器"23:23:23,00"计时器"23:23:23,00"&计时器计时器"13.23.23,00"&计时器"03:03:03.00"计时器&timer"0:00:00.00"否&cmd/v:on/c echo until middle=!TimeReEnter!对于那些不太可能但在执行过程中可能发生的时间格式更改,现在可以混合输入。

    2:函数:与批处理脚本捆绑在一起的计时器(示例用法如下):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    @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

    ::若要测试它,请复制代码段上方和下方的粘贴

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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代表冒号结束、点结束和冒号集合、点集合-用于混合格式支持