对时间值进行算术运算的延迟内循环扩展
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
我对批处理文件比较陌生,我一直在尝试让以下计时程序(灵感来自
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