0

当我在 FOR 循环中执行程序时,我编写了自己的代码来尝试计算延迟。缺点是值 %time% 是在同一时刻评估的。所以我想问你,是否可以更改代码以将 2 个计算块(使用 SET /A)移动到单独的子例程中。我用 goto 在网上搜索了这个解决方案,但我不清楚如何返回循环。作为我发现的例子,在文件末尾提到。

@echo off 
Setlocal EnableDelayedExpansion

FOR /F "tokens=*" %%A IN ('DATE/T') DO FOR %%B IN (%%A) DO SET Today=%%B
ECHO It's %Today% today

CHCP 1250 > NUL

SET tpath=TEMP

for /f "delims=" %%x in (delimiter.ini) do set TAB=%%x

if not exist proxies.ini (
  echo Proxies not Found!
  pause 
exit
)

REM Set array of proxies
FOR /F "eol= tokens=1,2 delims=%TAB%" %%A IN (proxies.ini) DO (
  if "%%A"=="*" (
    SET asterisk=1
    SET http_proxy=%%B
    SET t0=%time%
    wget.exe http://www.nasa.gov/images/content/297522main_image_1244_946-710.jpg 
    SET t1=%time%
    REM FOR /F %%A IN ('TIME/T') DO SET t1=%%A

    echo !t0!
    SET /a s = !t0:~6,2!*100
    SET /a c = !t0:~9,2!
    SET /a c = "!c!-(!c!/10)*4"
    SET /a d1 = !s!+!c!
    echo !s!+!c! = !d1!
    echo !d1!

    echo !t1!
    SET /a s = !t1:~6,2!*100
    SET /a c = !t1:~9,2!
    SET /a c = "!c!-(!c!/10)*4"
    SET /a d2 = !s!+!c!
    echo !s!+!c! = !d2!
    SET /a delay = !d1!-!d2!   
    echo Delay:!delay!

   pause
   Echo Working proxy ... !proxy!     
  )
)


pause

编辑 这是第二次测试,在 dBenham 发布他更好的解决方案之前:

@echo off 
Setlocal EnableDelayedExpansion

FOR /F "tokens=*" %%A IN ('DATE/T') DO FOR %%B IN (%%A) DO SET Today=%%B
ECHO It's %Today% today

CHCP 1250 > NUL

SET tpath=TEMP

for /f "delims=" %%x in (delimiter.ini) do set TAB=%%x

if not exist proxies.ini (
  echo Proxies not found. 
  pause 
exit
)

REM Set array of proxies
FOR /F "eol= tokens=1,2 delims=%TAB%" %%A IN (proxies.ini) DO (
  if "%%A"=="*" (
    SET asterisk=1
    SET http_proxy=%%B
    SET t0=!time!
    wget.exe http://www.nasa.gov/images/content/297522main_image_1244_946-710.jpg 
    call :setTime !t0! !time!
    SET t1=!time!

:setTime
   Setlocal EnableDelayedExpansion
    SET t0=%1
    SET t1=%2
    echo !t0! !t1!
    pause
    SET /a m1 = !t0:~3,2!
    SET /a s1 = !t0:~6,2!
    SET /a s = !s1!*100
    SET /a c = !t0:~9,2!
    SET /a c = "!c!-((!c!/10)*4)"
    SET /a d1 = !s!+!c!
    echo !s!+!c! = !d1!
    echo !d1!

    echo !t1!
    SET /a m2 = !t1:~3,2!
    SET /a s2 = !t1:~6,2!
    if "!m2!" GTR "!m1!" (
      IF "!s2!" LSS "!s1!" (
          REM e.g. s1=20, s2=04 => 
          SET /a s2_cor = 60-!s1!+!s2!
          echo Correction: s2: !s2!
          SET /a s2_cor = "!s2!+60*(!m2!-!m1!)" 
      ) ELSE (
          SET /a s2_cor = "!s2!+60*(!m2!-!m1!-1)"
      )

      SET /a s2 = "!s2!+!s2_cor!"
    )

    SET /a s = !s2!*100    
    echo s2:!s2! , s:!s!    
    SET /a c = !t1:~9,2!
    SET /a c = "!c!-((!c!/10)*4)"
    SET /a d2 = !s!+!c!
    echo !s!+!c! = !d2!
    SET /a delay = !d2!-!d1!   
    echo Delay:!delay!
   pause
   endlocal
exit /b

   Echo Working proxy ... !proxy!     
  )
)

if NOT !asterisk!==1 (
 echo .
 echo Asterix not set
 echo .
 exit
)
pause
4

2 回答 2

1

乔伊诊断出你的一个问题。但是您对经过时间的计算有很多问题。

  • 正如乔伊指出的那样,您需要在循环中使用延迟扩展

  • 您应该从 Time2 中减去 Time1。你正在做相反的事情。

  • 您对小数秒的处理是完全错误的。

  • 您假设经过的时间少于一分钟。这可能是真的,也可能不是。但是您错误地认为您只需要查看时间中的秒部分。如果 T0=09:59:59.99 和 T1=10:00:00.00 怎么办?正确的结果应该是 0.01 秒。获得正确结果的唯一方法是查看所有时间分量。计算该值的最简单方法是在进行任何减法之前将每次转换为午夜过后的厘秒数(1/100 秒)。

  • 如果 T0=23:59:59.99 和 T1=00:00:00.00 怎么办?正确的结果应该是 0.01 秒。但是,如果将两个值都转换为厘秒,然后从 T1 中减去 T0,您将得到一个负数。诀窍是如果结果是否定的,则将 1 天 (24*60*60*100) 添加到结果中。这允许该技术在一天中的任何时间计算小于 24 小时的任何时间间隔。

  • SET /A 将以 0 开头的任何数字解释为八进制表示法。因此,任何大于 7 的数字在您的代码中都会被错误地解释。像 08 和 09 这样的加值会引发错误,因为 8 和 9 不是有效的八进制数字。下面的解决方案使用一些数学技巧在每个时间分量之前添加一个数字以强制 SET /A 使用十进制表示法,然后在最后减去额外的时间。

其他问题:

  • 大多数情况下,使用 SET /A 您不需要扩展变量。例如,如果你想给一个数值变量加一,你可以简单地使用set /A var=var+1,或者更简洁set var+=1的 。

  • 我不认为你的 FOR /F 选项"eol= tokens=1,2 delims=%TAB%"正在做你想做的事。我怀疑您正在尝试禁用 EOL 选项,但实际上您正在将 EOL 设置为<space>字符。禁用它的正确方法是将 EOL 设置为您的 DELIM 值之一:"eol=%TAB% tokens=1,2 delims=%TAB%".

这是代码的相关部分,使用一些工作批处理子例程来计算经过的时间。我用于处理时间计算的算法源自此处的代码:http: //www.dostips.com/DtCodeFunctions.php#_Toc128586395

下面的代码中有很多高级批处理技术。如果其中大部分没有意义,请不要感到难过。但是您应该能够将子例程复制到您想要的任何脚本中并轻松计算经过的时间。

setlocal enableDelayedExpansion
FOR /F "eol= tokens=1,2 delims=%TAB%" %%A IN (proxies.ini) DO (
  if "%%A"=="*" (
    SET asterisk=1
    SET http_proxy=%%B
    SET t0=!time!
    wget.exe http://www.nasa.gov/images/content/297522main_image_1244_946-710.jpg
    SET t1=!time!

    call :diffTime t0 t1 Delay
    call :diffTime /f t0 t1 FormattedDelay
    echo Delay=!Delay!
    echo FormattedDelay=!FormattedDelay!

    pause
    Echo Working proxy ... !proxy!
  )
)
exit /b

:diffTime  [/F]  StartTimeVar  EndTimeVar  [ReturnVar]
::
:: Compute the elapsed time between the time values stored in
:: variables StartTimeVar and EndTimeVar. The value is returned
:: in units of centiseconds (1/100 second). If the /F option is
:: specified then the result is formatted as HH:MM:SS.DD
::
:: The result is returned in variable ReturnVar.
::
:: If ReturnVar is not specified then simply echo the result.
::
  setlocal enableDelayedExpansion
  set "diffTime.formatTime="
  if /i "%~1"=="/F" (
    set diffTime.formatTime=1
    shift /1
  )
  call :parseTime %1 diffTime.t1
  call :parseTime %2 diffTime.t2
  set /a "diff=diffTime.t2-diffTime.t1"
  if %diff% lss 0 set /a "diff+=24*60*60*100"
  if defined diffTime.formatTime (
    set /a "DD=diff, HH=DD/360000, DD-=HH*360000, MM=DD/6000, DD-=MM*6000, SS=DD/100, DD-=SS*100"%\n%
    if "!HH:~1!"=="" set "HH=0!HH!"
    if "!MM:~1!"=="" set "MM=0!MM!"
    if "!SS:~1!"=="" set "SS=0!SS!"
    if "!DD:~1!"=="" set "DD=0!DD!"
    set diff=!HH!:!MM!:!SS!.!DD!
  )
  endlocal & if "%~3"=="" (echo %diff%) else set "%~3=%diff%"
exit /b


:parseTime  TimeVar  ReturnVar
::
:: Parse the time value stored in TimeVar and compute the number of centiseconds (1/100 second) past midnight.
:: The result is returned in variable ReturnVar
::
  for /f "tokens=1-4 delims=:.," %%A in ("!%~1: =0!") do set /a "%~2=(((1%%A*60)+1%%B)*60+1%%C)*100+1%%D-36610100"
exit /b
于 2012-06-12T21:00:21.810 回答
0

实际上使用延迟扩展。在循环内使用!time!而不是。%time%同样对于您在循环中设置和使用的所有其他变量。

于 2012-06-12T18:25:12.590 回答