0

I have an array ${timearray[*]} that contains a number of times in this format

20:56 20:57 20:59 21:01 21:04

There is a second array ${productarray[*]} that contains different times

20:54 20:56 20:58 21:00 21:02

I need to get a difference between the two by subtracting time minus product. To do this I believe I need to convert these times into epoch time before subtracting, I'll then divide by 60 and round to the nearest minute. I attempted using a for loop like this to do the conversion.

arraylength=`expr ${#timearray[@]} -1`
for ((l=0; l<=$arraylength; l++))
do
    epochtimearray=(`date --date="${timearray[$l]}" +%s`)
done

However the resulting epochtimearray only contains the epoch value of the last time

echo ${epochtimearray[*]}
1472331840

Does anyone see what I'm missing here or is there a better way to subtract time times.

2
  • I really don't see why you need to use the epoch if you just have hours+minutes (which are of the same day or it is incomplete) Commented Aug 27, 2016 at 21:34
  • I believe that would cause an erroneous result when an element of the timearray has rolled over to 00:00 while the corresponding element of productarray is still at 23:59. Commented Aug 27, 2016 at 21:57

3 Answers 3

2

To add an element to an array, use the += operator:

epochtimearray+=(`date --date="${timearray[$l]}" +%s`)

or set the element at the given index:

epochtimearray[l]=(`date --date="${timearray[$l]}" +%s`)
Sign up to request clarification or add additional context in comments.

3 Comments

should be $l on the left.
@Jean-FrançoisFabre not true, array indices are always arithmetic context, so they don't need the $.
Thank you! This worked. I was forgetting to specify which element of the array within the loop. Each iteration would overwrite the one element, leaving only the last iteration as the sole element. Makes sense now.
0

This diffs a bunch of times - I don't recommend it for large numbers of values but it's definitely better than running date in a loop

# populate couple arrays
declare -a timearray=(20:56 20:57 20:59 21:01 21:04)
declare -a productarray=(20:54 20:56 20:58 21:00 21:02)

# convert multiple times for today into epoch seconds
IFS=$'\n'
timeepochs=($(echo "${timearray[*]}"|date -f- +%s))
prodepochs=($(echo "${productarray[*]}"|date -f- +%s))
unset IFS
for ((i=0; i < ${#timeepochs[*]}; ++i)); do
  echo "$i: ${timearray[i]} - ${productarray[i]} = $((timeepochs[i] - prodepochs[i])) seconds"
done

Comments

0

It is usually much easier to loop over array elements than to try to construct the indices:

for d in "${timearray[@]}"; do
  epochtimearray+=($(date "$d" +%s))
done

But if you are using Gnu grep (which apparently you are), you can use the -f option to process all the times with a single call:

epochtimearray=($(date +%s -f-<<<"$(IFS=$'\n'; echo "${timearray[*]}")"))

But you don't actually need to construct the temporary arrays; you can put the whole thing together using a couple of standard Unix utilities:

paste -d- <(date +%s -f-<<<"$(IFS=$'\n'; echo "${timearray[*]}")") \
          <(date +%s -f-<<<"$(IFS=$'\n'; echo "${productarray[*]}")") |
bc

That uses paste to combine the two lists into two vertical columns separated by a dash (-d-) and then feeds the resulting lines (which look a lot like subtractions :) ) into the calculator bc, which calculates the value of each line.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.