计算Windows批处理文件中的时差

Dan*_*ans 38 windows time batch-file

如何在批处理文件中获得两次差异?因为我想在HTML文件中打印它.

我认为这是可能的,但事实并非如此.

Set "tijd=%time%"
echo %tijd%
echo %time%-%tijd%
Run Code Online (Sandbox Code Playgroud)

结果:

11:07:48,85
11:16:58,99-11:07:48,85
Run Code Online (Sandbox Code Playgroud)

但我想要的是:

00:09:10,14
Run Code Online (Sandbox Code Playgroud)

或9分10秒或550秒

Aac*_*ini 58

@echo off

rem Get start time:
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
   set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)

rem Any process here...

rem Get end time:
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
   set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)

rem Get elapsed time:
set /A elapsed=end-start

rem Show elapsed time:
set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
if %mm% lss 10 set mm=0%mm%
if %ss% lss 10 set ss=0%ss%
if %cc% lss 10 set cc=0%cc%
echo %hh%:%mm%:%ss%,%cc%
Run Code Online (Sandbox Code Playgroud)

编辑2017-05-09: 添加了更短的方法

我开发了一种更短的方法来获得相同的结果,所以我忍不住在这里发布它.for用于分隔时间部分的两个命令和if用于在结果中插入前导零的三个命令被两个长的算术表达式替换,甚至可以组合成一个更长的行.

该方法包括将具有"HH:MM:SS.CC"格式的时间的变量直接转换为将时间转换为厘秒所需的公式,相应地给出下面给出的映射方案:

       HH        :      MM        :      SS        .       CC

(((10  HH  %%100)*60+1  MM  %%100)*60+1  SS  %%100)*100+1  CC  %%100
Run Code Online (Sandbox Code Playgroud)

也就是说,(((10在开头插入,更换冒号%%100)*60+1,更换点%%100)*100+1并插入%%100到底; 最后,将结果字符串计算为算术表达式.在时间变量中,有两个不同的子串需要替换,因此转换必须以两行完成.要获得经过的时间,请使用(endTime)-(startTime)表达式并替换同一行中的两个时间字符串.

编辑2017/06/14: 增加了区域独立调整

@echo off
setlocal EnableDelayedExpansion

set "startTime=%time: =0%"

set /P "=Any process here..."

set "endTime=%time: =0%"



rem Get elapsed time:
set "end=!endTime:%time:~8,1%=%%100)*100+1!"  &  set "start=!startTime:%time:~8,1%=%%100)*100+1!"
set /A "elap=((((10!end:%time:~2,1%=%%100)*60+1!%%100)-((((10!start:%time:~2,1%=%%100)*60+1!%%100)"

rem Convert elapsed time to HH:MM:SS:CC format:
set /A "cc=elap%%100+100,elap/=100,ss=elap%%60+100,elap/=60,mm=elap%%60+100,hh=elap/60+100"

echo Start:    %startTime%
echo End:      %endTime%
echo Elapsed:  %hh:~1%%time:~2,1%%mm:~1%%time:~2,1%%ss:~1%%time:~8,1%%cc:~1%
Run Code Online (Sandbox Code Playgroud)

您可以在此答案中查看此方法的详细说明.


Dan*_*ans 41

如下所述: 如何使用Windows批处理文件来衡量控制台应用程序的性能?

批量"程序"下面应该做你想要的.请注意,它以厘秒而不是毫秒输出数据.使用命令的精度只有几厘秒.

这是一个示例输出:

STARTTIME: 13:42:52,25
ENDTIME: 13:42:56,51
STARTTIME: 4937225 centiseconds
ENDTIME: 4937651 centiseconds
DURATION: 426 in centiseconds
00:00:04,26
Run Code Online (Sandbox Code Playgroud)

这是批处理脚本:

@echo off
setlocal

rem The format of %TIME% is HH:MM:SS,CS for example 23:59:59,99
set STARTTIME=%TIME%

rem here begins the command you want to measure
dir /s > nul
rem here ends the command you want to measure

set ENDTIME=%TIME%

rem output as time
echo STARTTIME: %STARTTIME%
echo ENDTIME: %ENDTIME%

rem convert STARTTIME and ENDTIME to centiseconds
set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100)
set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100)

rem calculating the duratyion is easy
set /A DURATION=%ENDTIME%-%STARTTIME%

rem we might have measured the time inbetween days
if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%

rem now break the centiseconds down to hors, minutes, seconds and the remaining centiseconds
set /A DURATIONH=%DURATION% / 360000
set /A DURATIONM=(%DURATION% - %DURATIONH%*360000) / 6000
set /A DURATIONS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000) / 100
set /A DURATIONHS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000 - %DURATIONS%*100)

rem some formatting
if %DURATIONH% LSS 10 set DURATIONH=0%DURATIONH%
if %DURATIONM% LSS 10 set DURATIONM=0%DURATIONM%
if %DURATIONS% LSS 10 set DURATIONS=0%DURATIONS%
if %DURATIONHS% LSS 10 set DURATIONHS=0%DURATIONHS%

rem outputing
echo STARTTIME: %STARTTIME% centiseconds
echo ENDTIME: %ENDTIME% centiseconds
echo DURATION: %DURATION% in centiseconds
echo %DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS%

endlocal
goto :EOF
Run Code Online (Sandbox Code Playgroud)

  • 不错,但仍然是一个重大的错误,正如迈克已经说过的那样.算法必须解决两种特殊行为(至少:-):1.第一种是批量认为前缀为零的数字是八进制数.通过在前缀"1"并再次减去100来正确地解决这个问题.但另一个问题是小时有时是一个数字("2:"),有时是两个("12:").也许这是特定于语言环境的,但我想,事实并非如此.所以":~02,2%"在这里失败了.然而,这并不总是有效,Aacini的解决方案似乎更好. (5认同)
  • Aacini的下面我认为更好,因为它更直接.此外,您的脚本会在我的系统上发出错误,并不总是执行数学运算.有时,我不确定问题是什么,但它现在没有这样做.. (2认同)

Mik*_*e Q 21

Aacini代码的重新哈希,因为很可能您将开始时间设置为变量并希望将该数据保存为输出:

    @echo off

    rem ******************  MAIN CODE SECTION
    set STARTTIME=%TIME%

    rem Your code goes here (remove the ping line)
    ping -n 4 -w 1 127.0.0.1 >NUL

    set ENDTIME=%TIME%

    rem ******************  END MAIN CODE SECTION


    rem Change formatting for the start and end times
    for /F "tokens=1-4 delims=:.," %%a in ("%STARTTIME%") do (
       set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )

    for /F "tokens=1-4 delims=:.," %%a in ("%ENDTIME%") do (
       set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )

    rem Calculate the elapsed time by subtracting values
    set /A elapsed=end-start

    rem Format the results for output
    set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
    if %hh% lss 10 set hh=0%hh%
    if %mm% lss 10 set mm=0%mm%
    if %ss% lss 10 set ss=0%ss%
    if %cc% lss 10 set cc=0%cc%

    set DURATION=%hh%:%mm%:%ss%,%cc%

    echo Start    : %STARTTIME%
    echo Finish   : %ENDTIME%
    echo          ---------------
    echo Duration : %DURATION% 
Run Code Online (Sandbox Code Playgroud)

输出:

    Start    : 11:02:45.92
    Finish   : 11:02:48.98
             ---------------
    Duration : 00:00:03,06
Run Code Online (Sandbox Code Playgroud)


Lle*_*nes 15

如果您不介意在批处理脚本中使用 powershell:

@echo off
set start_date=%date% %time%
:: Simulate some type of processing using ping
ping 127.0.0.1  
set end_date=%date% %time%
powershell -command "&{$start_date1 = [datetime]::parse('%start_date%'); $end_date1 = [datetime]::parse('%date% %time%'); echo (-join('Duration in seconds: ', ($end_date1 - $start_date1).TotalSeconds)); }"
Run Code Online (Sandbox Code Playgroud)