对时间值进行算术运算的延迟内循环扩展

Delayed Expansion Inside Loop with Arithmetic Operations on Time Values

我对批处理文件比较陌生,我一直在尝试让以下计时程序(灵感来自 )工作:

set "startTime=%time: =0%"

@rem Removing milliseconds information
set startTime=%startTime:~0,-3%

setlocal EnableDelayedExpansion

for %%i in (1 2 3 4 5) do (

   timeout /T 3 /NOBREAK

   set endTime=!time: =0!
   set endTime=!endTime:~0,-3!

   set /A "ss=(((1%endTime::=-100)*60+1%-100)-(((1%startTime::=-100)*60+1%-100)"
   set /A "hh=ss/3600+100,ss%%=3600,mm=ss/60+100,ss=ss%%60+100"

   @rem Get format in HH:MM:SS (maybe H:MM:SS after midnight.. not tested yet)
   echo Start time: %startTime%
   echo End time: !endTime!

   @rem Issue here: Always get the same output despite delayedExpansion active
   echo Diff time: !ss!

   echo.

   @rem Issue here: Not getting expected values
   echo Elapsed time: !hh:~1!:!mm:~1!:!ss:~1!...
   echo.

)
endlocal

我不太清楚为什么尽管延迟扩展,但时差的输出值总是相同的。另外,格式化的时间没有给我正确的值。

感谢您的帮助!

首先,感谢您提供的有用评论,帮助我找到了问题的解决方案。如果它可能对其他人有帮助,我会在此处发布解决方案。

如评论中所述,关键是确定我的操作系统使用的格式。

适用于我的代码如下,灵感来自 https://www.py4u.net/discuss/2286184

@rem Check that the format of %TIME% is HH:MM:SS.CS for example 23:59:59.99
echo "%TIME%"


set STARTTIME=%TIME%

@rem convert start time 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)

setlocal EnableDelayedExpansion

for %%i in (1 2 3 4 5) do (

   timeout /T 3 /NOBREAK
   
   set ENDTIME=!TIME!

   @rem convert ENDTIME to centiseconds
   @rem I found that double-quotes with set /A and numbers are needed inside the for loop
   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 Adjust for cases where timings over multiple days
   if !ENDTIME! LSS %STARTTIME% set set /A DURATION=%STARTTIME%-!ENDTIME!
   
   @rem now break the centiseconds down to hours, 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 Enforce double-digit format
   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 timings
   echo STARTTIME: %STARTTIME% centiseconds
   echo ENDTIME: !ENDTIME! centiseconds
   echo DURATION: !DURATION! in centiseconds
   echo Elapsed time: !DURATIONH!:!DURATIONM!:!DURATIONS!.!DURATIONHS!

  
)
endlocal