30} Can one calculate the difference between two times in a script?
Yes, one can:
@echo off & setlocal enableextensions
set /a diffSec=60*60*%4+60*%5+%6-(60*60*%1+60*%2+%3)
if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60
::
set /a h=(%diffSec%/3600)
set /a m=(%diffSec%/60)-60*%h%
set /a s=%diffSec%-60*(%diffSec%/60)
::
echo hrs=%h% min=%m% sec=%s%
::
endlocal & goto :EOF
For example
C:\_D\TEST>cmdfaq 12 13 56 17 4 57
hrs=4 min=51 sec=1
Next apply to get the duration of a task. Use Visual Basic Script
(VBScript) aided command line scripting for better locale independence.
@echo off & setlocal enableextensions
call :GetTime hh1_ mn1_ ss1_
echo hh1_=%hh1_% mn1_=%mn1_% ss1_=%ss1_%
rem Do whatever, like delay for demonstration:
ping -n 3 127.0.0.1>nul
call :GetTime hh2_ mn2_ ss2_
echo hh2_=%hh2_% mn2_=%mn2_% ss2_=%ss2_%
call :TimeDiff %hh1_% %mn1_% %ss1_% %hh2_% %mn2_% %ss2_% hh_ mn_ ss_
echo hh_=%hh_% mn_=%mn_% ss_=%ss_%
endlocal & goto :EOF
::
::=============================================================
:GetTime
setlocal enableextensions
set vbs_=%temp%\tmp.vbs
echo FixedTime=Time>"%vbs_%"
echo WScript.Echo Hour(FixedTime) ^&" "^& ^
Minute(FixedTime) ^&" "^& ^
Second(FixedTime) >> "%vbs_%"
for /f "tokens=1-3" %%a in ('cscript //nologo "%vbs_%"') do (
set hh_=%%a
set mn_=%%b
set ss_=%%c)
for %%f in ("%vbs_%") do if exist %%f del %%f
endlocal&set "%1=%hh_%"&set "%2=%mn_%"&set "%3=%ss_%"&goto :EOF
::
::=============================================================
:TimeDiff
setlocal enableextensions
set /a diffSec=60*60*%4+60*%5+%6-(60*60*%1+60*%2+%3)
if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60
set /a h=(%diffSec%/3600)
set /a m=(%diffSec%/60)-60*%h%
set /a s=%diffSec%-60*(%diffSec%/60)
endlocal&set "%7=%h%"&set "%8=%m%"&set "%9=%s%"&goto :EOF
The output would be something like
C:\_D\TEMP>cmdfaq
hh1_=8 mn1_=11 ss1_=1
hh2_=8 mn2_=11 ss2_=3
hh_=0 mn_=0 ss_=2
The problem with the above is the low resolution (seconds max). We
could also use
echo %time% but then we
run into the problems with localization (like where the am/pm or the
24-hour format is on). However, for short intervals taking seconds and
the hundreds of seconds could suffice.
@echo off & setlocal enableextensions
call :GetTime100 hh1_ mn1_ ss1_ sh1_
echo hh1_=%hh1_% mn1_=%mn1_% ss1_=%ss1_% sh1_=%sh1_%
rem Do whatever, like delay for demonstration:
ping -n 1 127.0.0.1>nul
call :GetTime100 hh2_ mn2_ ss2_ sh2_
echo hh2_=%hh2_% mn2_=%mn2_% ss2_=%ss2_% sh2_=%sh2_%
call :TimeDiff100 %hh1_% %mn1_% %ss1_% %sh1_% %hh2_% %mn2_% %ss2_% %sh2_% diff_
echo %diff_%
endlocal & goto :EOF
::
::=============================================================
:GetTime100
setlocal enableextensions
for /f "tokens=1-4 delims=:.;" %%a in ('echo %time%') do (
set hh_=%%a
set mn_=%%b
set ss_=%%c
set s100_=%%d)
call :Trim %hh_% hh_
call :Trim %mn_% mn_
call :Trim %ss_% ss_
call :Trim %s100_% s100_
endlocal&set "%1=%hh_%"&set "%2=%mn_%"&set "%3=%ss_%"&set "%4=%s100_%"&goto :EOF
::
::=============================================================
:Trim
setlocal enableextensions
echo %1|findstr [123456789]>nul
if %errorlevel% EQU 0 (
for /f "tokens=* delims=0 " %%a in ('echo %~1') do (
set Return_=%%a)
) else (set Return_=0)
endlocal & set "%2=%Return_%" & goto :EOF
::
::=============================================================
:TimeDiff100
setlocal enableextensions
set /a diffSec=100*60*60*%5+100*60*%6+100*%7+%8-(100*60*60*%1+100*60*%2+100*%3+%4)
if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60*100
endlocal & set "%9=%diffSec%" & goto :EOF
Examples of the output
C:\_D\TEST>cmdfaq
hh1_=8 mn1_=55 ss1_=6 sh1_=50
hh2_=8 mn2_=55 ss2_=8 sh2_=5
155
C:\_D\TEST>cmdfaq
hh1_=8 mn1_=55 ss1_=15 sh1_=0
hh2_=8 mn2_=55 ss2_=16 sh2_=43
143
C:\_D\TEST>cmdfaq
hh1_=8 mn1_=55 ss1_=51 sh1_=30
hh2_=8 mn2_=55 ss2_=51 sh2_=78
48