简体   繁体   中英

How I substract 2 timestamps using shell scripts

I need to subtract the below 2 times using a shell script

var1=2019-11-14-03.00.02.000000

var2=2019-11-14-03.00.50.000000

The output should be 00-00-00-00.00.48.00000

First convert var1 and var2 to date in seconds (since epoch) with:

sec1=$(date --date $var1 +%s)
...

Use bash math operators to calculate the difference

delta=$((sec1 - sec2))

Finally convert it back to a readable format

date --date @1502938801"$delta"

As mentioned in my comment, var1 and var2 are not valid date formats for passing to GNU date with the -d option. Before you can convert the times to seconds from epoch, you must

  • remove the '-' between the date and time portions of each variable,
  • isolate the time alone,
  • remove the milliseconds
  • replace all '.' in the time with ':'
  • restore the milliseconds separated from the time with '.'
  • pass the reformatted string for each to date -d"$dt $tm" +%s with the reformatted date and time space-separated.

Bash provides parameter substitutions to handle each very easily.

After computing the time since epoch for both and taking the difference, you then have to manually compute the difference in years, months, days, hours, minutes, seconds and milliseconds in order to output the difference and you must format the output using printf and the integer conversion specifier using both the appropriate field-width and leading-zero modifiers.

Putting it altogether, (and using a 365-day/year and 30-day/mo approximation) you could do:

#!/bin/bash

var1=2019-11-14-03.00.02.000000
var2=2019-11-14-03.00.50.000000

dt1=${var1%-*}      ## isolate date portion of variables
dt2=${var2%-*}

tm1=${var1##*-}     ## isolate time portion of variables
tm2=${var2##*-}

ms1=${tm1##*.}      ## isolate milliseconds portion of variables
ms2=${tm2##*.}

tm1=${tm1%.*}       ## remove milliseconds from time
tm2=${tm2%.*}

tm1=${tm1//./:}     ## substitute all . with : in times w/o milliseconds
tm2=${tm2//./:}

tm1=${tm1}.$ms1     ## restore milliseconds
tm2=${tm2}.$ms2

epoch1=$(date -d"$dt1 $tm1" +%s)    ## get time since epoch for both
epoch2=$(date -d"$dt2 $tm2" +%s)

epochdiff=$((epoch2-epoch1))        ## get difference in epoch times

## Approximates w/o month or leap year considerations
y=$((epochdiff/(3600*24*365)))      ## years difference
rem=$((epochdiff-y))                ## remainder
m=$((rem/(3600*24*30)))             ## months difference (based on 30 day mo)
rem=$((rem-m))                      ## remainder
d=$((rem/(3600*24)))                ## days difference
rem=$((rem-m))                      ## remainder
H=$((rem/3600))                     ## hours difference
rem=$((rem-H))                      ## remainder
M=$((rem/60))                       ## minutes difference
S=$((rem-M))                        ## secnds difference
ms=$((ms2-ms1))                     ## millisecond difference

## format output
printf "%04d-%02d-%02d-%02d:%02d:%02d.%04d\n" $y $m $d $H $M $S $ms

( note: you can further fine-tune the month and year/leap-year calculations -- that is left to you)

Example Use/Output

$ bash ~/scr/dtm/fulltimediff.sh
0000-00-00-00:00:48.0000

Look things over and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM