I have a file that contains a set of Timestamps in format of H:M:S.MS
, I can read and print all of the saved Timestamps but when I do some arithmetic operation like Subtract (say Timestamp2 - Timestamp1
) it doesn't give me the answer, I do not have experience work with bash script programming.
Any suggestions, recommendations will be much appreciated.
Here is the screen shot of my problem.
Here is an example :
Start Time = 17:53:01.166721
End Time = 17:53:01.369787
The expected result for End Time - Start Time
is either 0:00:0.203066
or 0.203066
.
If you want to process the date using simple command line tools, you need to convert the timestamps into some easy-to-deal-with format, like epoch-based.
You can do this with the date
command, which you can wrap in a function like so:
timestamp() {
date '+%s%N' --date="$1"
}
# timestamp '2020-01-01 12:20:45.12345' => 1577899245123450000
Then you can subtract them directly:
echo $(( $(timestamp "$etime") - $(timestamp "$stime") ))
Note that the %N
format specifier (nanoseconds) is a GNU extension and is not handled in the default macOS date
command. Either (a) brew install coreutils
and use gdate
in the function above or (b) use this alternative function on macOS (but note it lacks support for sub-second measurements):
timestamp() {
local format='%Y-%m-%d %H:%M:%S' # set to whatever format is used
date -j -f "$format" "$1" '+%s'
}
# timestamp '2020-01-01 12:20:45' => 1577899245
If you need to use bash, you need to convert the timestamp into an integer value:
$ time="12:34:56.789"
$ IFS=":." read -r h m s ms <<<"$time"
$ echo $h $m $s $ms
12 34 56 789
$ milliseconds=$(( (h*3600 + m*60 + s)*1000 + ms ))
$ echo $milliseconds
45296789
Then you can subtract to get a number of milliseconds representing the diff.
Convert to seconds with some arithmetic and string construction:
$ seconds="$((milliseconds / 1000)).$((milliseconds % 1000))"
$ echo $seconds
45296.789
To address gniourf_gniourf's valid point (in a clunky way):
$ time="12:34:56.7"
$ IFS=":." read -r h m s ms <<<"$time"
$ ms="${ms}000"; ms=${ms:0:3}
$ echo $h $m $s $ms
12 34 56 700
# .......^^^
Also, strings that are invalid octal numbers like "08" and "09" will throw errors in bash arithmetic, so explicitly declare they are base 10
milliseconds=$(( (10#$h*3600 + 10#$m*60 + 10#$s)*1000 + 10#$ms ))
Assuming your variables are integers, you need to enclose your calculation in an arithmetic evaluation for that to work.
echo $(( VAR1 - VAR2 ))
Or, if you want to assign the value :
VAR3=$(( VAR1 - VAR2 ))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With