Simple way to convert HH:MM:SS (hours:minutes:seconds.split seconds) to seconds

Viewed 38529

What's an easy way to convert 00:20:40.28 (HH:MM:SS) to seconds with a Bash script?

Split seconds can be cut out, it’s not essential.

13 Answers

Try awk. As a bonus, you can keep the split seconds.

echo "00:20:40.25" | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'

Try this:

T='00:20:40.28'
SavedIFS="$IFS"
IFS=":."
Time=($T)
Seconds=$((${Time[0]}*3600 + ${Time[1]}*60 + ${Time[2]})).${Time[3]}
IFS="$SavedIFS"

echo $Seconds

($<string>) splits <string> based on the splitter (IFS).

${<array>[<index>]} returns the element of the <array> at the <index>.

$((<arithmetic expression>)) performs the arithmetic expression.

Hope this helps.

echo "40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
40.25
echo "10:40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
640.25
echo "20:10:40.25" | awk -F: '{ if (NF == 1) {print $NF} else if (NF == 2) {print $1 * 60 + $2} else if (NF==3) {print $1 * 3600 + $2 * 60 + $3} }'
72640.25

I haven't tested this but, I think this is how you'd split the string. Followed by multiplying by the appropriate amounts for hours and minutes.

mytime=’00:20:40.28′
part1=${mytime%%:*}; rest=${mytime#*:}
part2=${rest%%:*}; rest=${rest#*:}
part3=${rest%%:*};

with the shell,

#!/bin/bash

d="00:20:40.28"
IFS=":"
set -- $d
hr=$(($1*3600))
min=$(($2*60))
sec=${3%.*}
echo "total secs: $((hr+min+sec))"

I have this old shell function (/bin/sh compatible in the sense of POSIX shell, not bash) which does this conversion in integer math (no fractions in the seconds):

tim2sec() {
    mult=1
    arg="$1"
    res=0
    while [ ${#arg} -gt 0 ]; do
        prev="${arg%:*}"
        if [ "$prev" = "$arg" ]; then
            curr="${arg#0}"  # avoid interpreting as octal
            prev=""
        else
            curr="${arg##*:}"
            curr="${curr#0}"  # avoid interpreting as octal
        fi
        curr="${curr%%.*}"  # remove any fractional parts
        res=$((res+curr*mult))
        mult=$((mult*60))
        arg="$prev"
    done
    echo "$res"
}

Outputs:

$ tim2sec 1:23:45.243
5025

It works with SS, MM:SS and HH:MM:SS only :)

TZ=utc date +'%s' -d "1970-01-01 00:00:38"

I think the easiest would be to count from the epoch time as:

$ date_var="00:20:40.28";
$ date +'%s.%3N' -d "1970-01-01 $date_var" --utc
1240.280

You can also easily change the format to your need.

Related