-1

I've been trying to read line by line from text file. In each line, I do have "starttime" & "endtime" field in 3 & 4 th column as I highlighted below.

File1,110543,2020-07-18T03:09:12.1321687+00:00,2020-07-18T03:10:22.4097433+00:00,000001

File2,210543,2020-07-18T04:19:28.0459100+00:00,2020-07-18T04:26:08.6626472+00:00,000002

I just want to find the difference between "starttime" & "endtime" column using below script.

@Echo off&Setlocal EnableExtensions EnableDelayedExpansion
IF EXIST "%csvFilePath%tempfile.txt"  ( 
( for /f "tokens=1-5 delims=," %%A in (%csvFilePath%tempfile.txt) do (
echo fileRecord %%A,%%B,%%C,%%D,%%E
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%C") Do (
    set starttime=%%b:%%c:%%d
)
for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%D") Do (
    set endtime=%%b:%%c:%%d
)   
echo !starttime!
echo !endtime! 
set options="tokens=1-4 delims=:.,"
for /f %options% %%a in (!starttime!) do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in (!endtime!) do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1

set /a hours=%end_h%-%start_h%
set /a mins=%end_m%-%start_m%
set /a secs=%end_s%-%start_s%
set /a ms=%end_ms%-%start_ms%
if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms%
if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs%
if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins%
if %hours% lss 0 set /a hours = 24%hours%
if 1%ms% lss 100 set ms=0%ms%

:: Mission accomplished
set /a totalsecs = %hours%*3600 + %mins%*60 + %secs%
echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total))))
    

start(03:09:12) & endtime(03:10:22) value is being printed for line1 as expected when I'm using !starttime! & !endtime!. I'm trying to pass the same variable to calculate the difference in below line.

for /f %options% %%a in (!starttime!) do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in (!endtime!) do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1

after execution, I'm getting "0 was unexpected at this time". Can you pls help me on this

  • Your code structure is not clear to me. Check parentheses. Three obvious points though: to process a string, enclose it in quotes: `for /f %options% %%a in ("!starttime!") do` and the `)` in the `echo command took...` line has to be escaped (`^)`) to not end the code block and a (malformed) label is not allowed within a loop/codeblock. Use `REM` instead of `::` for comments. – Stephan Jul 23 '20 at 11:24
  • Hi Stephen, Thanks for your reply!! Parentheses are placed correctly. when I copied the code here the parentheses were listed outside of the code block. Hence, I just manually appended the parentheses inside code block. And, I tried with "!starttime!" double quote as well still getting the same error. – OrionRaiders Jul 23 '20 at 12:15

1 Answers1

0

There are some issues in your code:

  1. don't use :: as a comment. Especially within a code block. It might break your code or lead to unexpected and hard to troubleshoot results.
  2. you need delayed expansion for all variables defined in the code block (you used delayed expansion for a few variables, but not for all.
  3. set /a doesn't need % or ! at all (optional, but here you'd need ! instead of %).
  4. to process a string with for /f, it needs to be quoted, or for tries to find a file with that name.
  5. You had a superfluent pair of parentheses.
  6. %csvFilePath% is not defined.
  7. for /f %options% ... works, but not with delayed variables, so I moved the declaration of %options% out of the loop.
  8. Your code was not properly indented, so the structure was hardly recognizable (I spotted the lack of delayed expansion only after indenting, which made it blatantly obvious)

Your code with all those issues fixed:

@Echo off
Setlocal EnableExtensions EnableDelayedExpansion
set "options=tokens=1-4 delims=:.,"
IF EXIST "%csvFilePath%tempfile.txt"  ( 
  for /f "tokens=1-5 delims=," %%A in (%csvFilePath%tempfile.txt) do (
    echo fileRecord %%A,%%B,%%C,%%D,%%E
    for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%C") Do set starttime=%%b:%%c:%%d
    for /f "tokens=1,2,3,4 delims=T:." %%a in ("%%D") Do set endtime=%%b:%%c:%%d
    echo !starttime!
    echo !endtime! 
    for /f "%options%" %%a in ("!starttime!") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
    for /f "%options%" %%a in ("!endtime!") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 1
    set /a hours=end_h-start_h
    set /a mins=end_m-start_m
    set /a secs=end_s-start_s
    set /a ms=end_ms-start_ms
    if !ms! lss 0 set /a secs = secs - 1 & set /a ms = 100!ms!
    if !secs! lss 0 set /a mins = mins - 1 & set /a secs = 60!secs!
    if !mins! lss 0 set /a hours = hours - 1 & set /a mins = 60!mins!
    if !hours! lss 0 set /a hours = 24!hours!
    if 1!ms! lss 100 set ms=0!ms!
    REM Mission accomplished
    set /a totalsecs = hours*3600 + mins*60 + secs
    echo command took !hours!:!mins!:!secs!.!ms! (!totalsecs!.!ms!s total^)
  )
)

(Note: I didn't check your math - I trust you there, as the results seem plausible)

Output with your example file:

fileRecord File1,110543,2020-07-18T03:09:12.1321687+00:00,2020-07-18T03:10:22.4097433+00:00,000001
03:09:12
03:10:22
command took 0:1:10.00 (70.00s total)
fileRecord File2,210543,2020-07-18T04:19:28.0459100+00:00,2020-07-18T04:26:08.6626472+00:00,000002
04:19:28
04:26:08
command took 0:6:40.00 (400.00s total)
Stephan
  • 53,940
  • 10
  • 58
  • 91