-1

Given two times say 2021-06-25T04:04:28Z and 2021-06-18T19:36:31Z where the first time means June 26, 2021 at 4:04am (+28 seconds) and the second time means June 18, 2021 at 7:36pm (+31 seconds). I would like to write a bash script that compares the two times and could tell me if the two events are separated by less than 20 minutes. Is there a function that does this or will I have to try and parse it then do a comparison that way. So for the above input I would like to echo "Times are not within 20 minutes of each other"

Thank you!

Matt
  • 13
  • 1
  • 2
  • Please read [this guide](https://stackoverflow.com/help/asking) to asking questions well. http://idownvotedbecau.se/noattempt/ – Paul Hodges Jun 25 '21 at 20:18

2 Answers2

4

The date command can parse and convert date/time data.

$: a=$( date --date="2021-06-18T19:36:31Z" +%s )
$: b=$( date --date="2021-06-25T04:04:28Z" +%s )

the %s format outputs the result in seconds since 1/1/70.

$: echo $a $b
1624044991 1624593868

so you can do simple integer math with it.

$: secs=$(( b - a ))
$: secs=${secs#-}    # get the absolute value
$: if (( secs < ( 20 * 60 ) )); then echo "within 20m"; else echo ">20m"; fi
>20m
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
  • 1
    Note that the `date` command is not very portable between platforms. The commands here will work on Linux, but not on BSD or macOS. – Gordon Davisson Jun 25 '21 at 20:20
  • Very true. If you have GNU `awk` it has time functions that can be used, but I think they aren't standard for other versions. It's always possible to roll your own, or use a language with them built in like `perl`. – Paul Hodges Jun 25 '21 at 20:22
  • I actually made a point to subtract later from earlier, and fogot to mention that you'll want the absolute value. I added `secs=${secs#-}` as a hack for just-in-case. – Paul Hodges Jun 25 '21 at 20:56
3

is a portable way to parse timestamps (MacOS does not ship with GNU date, although it is easily installed)

t1=2021-06-25T04:04:28Z
t2=2021-06-18T19:36:31Z

diff=$(
    perl -MTime::Piece -E '
        $fmt = "%Y-%m-%dT%H:%M:%SZ";
        $t1 = Time::Piece->strptime($ARGV[0], $fmt)->epoch;
        $t2 = Time::Piece->strptime($ARGV[1], $fmt)->epoch;
        say abs($t1 - $t2);
    ' "$t1" "$t2"
)

mins=20
if ((diff <= 60 * mins)); then
    echo "within $mins mins: $t1 and $t2"
else
    echo "greater than $mins mins: $t1 and $t2"
fi
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • This also has the nice feature of getting an absolute value and not having to worry about which point in time came first. – Paul Hodges Jun 25 '21 at 20:52