Как измерить время выполнения команды в командной строке Windows?

Есть ли встроенный способ измерения времени выполнения команды в командной строке Windows?

Ответ 1

Если вы используете Windows 2003 (обратите внимание, что Windows Server 2008 и более поздние версии не поддерживаются), вы можете использовать набор ресурсов Windows Server 2003 Resource Kit, который содержит 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

Вы можете получить TimeIt в наборе ресурсов Windows 2003. Загрузите его здесь.

Ответ 2

Кроме того, Windows PowerShell имеет встроенную команду, которая похожа на команду Bash time. Он называется "Measure-Command". Вы должны убедиться, что 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

Ответ 3

Если вы хотите

  • Чтобы измерить время выполнения до сотой доли секунды в формате (hh: mm: ss.ff)
  • Чтобы не загружать и устанавливать пакет ресурсов
  • Чтобы выглядеть как огромный DOS-ботаник (кто этого не делает)

Попробуйте скопировать следующий script в новый пакетный файл (например, 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 часа и более.

Ответ 4

Хе-хе, самым простым решением может быть следующее:

echo %time%
YourApp.exe
echo %time%

Это работает на каждой Windows из коробки.


В случае приложения, использующего консольный вывод, было бы удобно хранить время начала во временной переменной:

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

Ответ 5

Просто небольшое расширение ответа от Casey.K об использовании Measure-Command from PowerShell:

  • Вы можете вызвать PowerShell из стандартной командной строки, например:

    powershell -Command "Measure-Command {echo hi}"
    
  • Это будет стандартный вывод, но вы можете предотвратить это, добавив | Out-Default, как это из PowerShell:

    Measure-Command {echo hi | Out-Default}
    

    Или из командной строки:

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

Конечно, вы можете обернуть это в файл script *.ps1 или *.bat.

Ответ 6

Однострочный ящик, используемый в Windows Server 2008 R2:

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

До тех пор, пока mycommand не требует котировок (которые винты с обработкой кодов cmd). /v:on означает, что два разных значения TIME будут оцениваться независимо, а не один раз при выполнении команды.

Ответ 7

Если у вас открыто командное окно и вызовите команды вручную, вы можете отобразить временную метку в каждом приглашении, например.

prompt $d $t $_$P$G

Это дает вам что-то вроде:

23.03.2009 15:45:50,77

C:\>

Если у вас есть небольшая партия script, которая выполняет ваши команды, перед каждой командой должна быть пустая строка, например

(пустая строка)

myCommand.exe

(следующая пустая строка)

myCommand2.exe

Вы можете рассчитать время выполнения каждой команды по информации о времени в подсказке. Лучше всего, вероятно, было бы подключить вывод к текстовому файлу для дальнейшего анализа:

MyBatchFile.bat > output.txt

Ответ 8

Так как другие рекомендуют устанавливать такие вещи, как freeware и PowerShell, вы также можете установить Cygwin, что даст вам доступ ко многим базовым Unix команды, такие как time:

[email protected]:~$ time sleep 5

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

Не уверен, сколько добавочных ресурсов Cygwin добавляет.

Ответ 9

Не так элегантно, как некоторые функции в 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:

Ответ 10

Я использую бесплатное программное обеспечение под названием "GS Timer".

Просто создайте пакетный файл следующим образом:

timer
yourapp.exe
timer /s

Если вам нужен набор раз, просто подключите вывод таймера /s в файл .txt.

Вы можете получить его здесь: Gammadyne Free DOS Utilities


Разрешение составляет 0,1 секунды.

Ответ 11

Я использую 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 <[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

Ответ 12

Пока он длится не более 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.

Ответ 13

Там также TimeMem (март 2012):

Это утилита Windows, которая выполняет программу и отображает ее времени выполнения, использования памяти и статистики ввода-вывода. Это похоже на функциональность утилиты времени Unix.

Ответ 14

Это однострочный, который позволяет избежать отложенного расширения, что может нарушить определенные команды:

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.


Update

Вот улучшенный однострочный (без отложенное расширение):

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.

Ответ 15

Вот

Версия таймера 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

Ответ 16

В случае, если кто-то еще пришел сюда, чтобы найти ответ на этот вопрос, есть функция Windows API, называемая GetProcessTimes(). Это не похоже на слишком много работы, чтобы написать небольшую программу на языке C, которая запускает команду, выполняет этот вызов и возвращает время процесса.

Ответ 17

Это комментарий/править для Люка Сэмпсона приятный timecmd.bat и ответьте на

По какой-то причине это дает мне результат всего целых секунд... что для меня бесполезно. Я имею в виду, что я запускаю timecmd pause, и это всегда приводит к 1,00 с, 2,00 с, 4,00 сек... даже 0.00 сек! Windows 7. - Камило Мартин Сен 25 '13 в 16:00 "

В некоторых конфигурациях разделители могут отличаться. Следующие изменения должны охватывать, по крайней мере, большинство западных стран.

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

%time% миллисекунды работают над моей системой, добавив, что ','

(* потому что сайт не разрешает анонимный комментарий и не сохраняет хороший идентификатор, хотя я всегда использую тот же гостевой адрес электронной почты, который в сочетании с ipv6 ip и отпечатком от браузера должен быть достаточно, чтобы однозначно идентифицировать без пароля)

Ответ 18

  • В каталоге, где находится ваша программа, введите notepad mytimer.bat, нажмите "да", чтобы создать новый файл.

  • Вставьте код ниже, заменив YourApp.exe на свою программу, а затем сохраните.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
    
  • Введите mytimer.bat в командной строке и нажмите Enter.

Ответ 19

Process Explorer покажет время ядра, время пользователя и время на стене (и много других вещей), если вы нажмете на перед тем, как он выйдет. Это не инструмент командной строки, но в любом случае он очень полезен.

Ответ 20

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

Ответ 21

Следующий script использует только "cmd.exe" и выводит количество миллисекунд с момента создания конвейера до момента завершения процесса, предшествующего script. т.е. введите команду и переместите ее в script. Пример: "timeout 3 | runtime.cmd" должен давать что-то вроде "2990". Если вам нужен как выход во время выполнения, так и вывод stdin, перенаправление stdin перед каналом - ex: "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

Ответ 22

Следующий script эмулирует * nix эпоху, но он локальный и региональный. Он должен обрабатывать случаи края календаря, включая високосные годы. Если 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

Ответ 23

Ответ 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 часа.

Ответ 24

Вот мой метод, без преобразования и без ms. Полезно определять длительность кодирования (ограниченное до 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

Ответ 25

Для Luke Sampson nice script, поправки для отрицательных значений должны быть выполнены в обратном порядке, так как они могут сделать отрицательное значение 0 раньше.

Возьмем, например, время, когда начальное вычитание дает 1 час, 0 мин. и -29 секунд. Как сделано в сообщении, результат будет 1 час, -1 мин и 31 секунда. Если секунды исправлены до минут и минут до часов, вы получаете 31 секунду, 59 минут, 0 часов.

Ответ 26

Использование 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

Ответ 27

"Lean and Mean" TIMER с региональным форматом, 24h и поддержкой смешанного ввода
Адаптация тела метода замены Aacini, без IF's, только один 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 и таймаут /t 3 и echo 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: Функция : таймер в комплекте с пакетом script (пример использования ниже):

@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 означают конец дна, конец точки и набор двоеточия, набор точек - используется для поддержки смешанного формата

Ответ 28

мой код дает вам время работы в миллисекундах, до 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% чтобы отобразить ее.