bashdate

Calculate the difference between two timestamps in bash


I want to find out total system boot time by subtracting two timestamps. First I use this command to get the start time and end time:

sudo journalctl | grep "Logs begin at" | awk '{print $6" "$7" "$12" "$13}'

which gets me the following output:

2020-05-21 05:52:47 2020-05-28 19:37:36

(The first two fields being the start time and the last two fields being the end time)

Now I want to find the difference between the start time and end time, preferably in the format:

"0 year(s), 0 month(s), 7 day(s), HH:MM:SS"


Solution

  • What about this?

    #!/usr/bin/env bash
    echo "BASH_VERSION:" $BASH_VERSION 
    
    line="2020-05-21 05:52:47;2020-05-28 19:37:36"
    IFS=';' read -a dates <<< $line
    startDatetime=${dates[0]}
    endDatetime=${dates[1]}
    
    echo "| dates -> " ${dates[@]}
    echo "|> startDatetime -> ${startDatetime}"
    echo "|> endDatetime -> ${endDatetime}"
    
    startTime=$(date -jf "%Y-%m-%d %H:%M:%S" "${startDatetime}" +%s)
    endTime=$(date -jf "%Y-%m-%d %H:%M:%S" "${endDatetime}" +%s)
    diffSeconds="$(($endTime-$startTime))"
    
    echo "Diff in seconds: $diffSeconds"
    # at this point you have the diff in seconds and you can parse it however you want :)
    
    diffTime=$(gdate -d@${diffSeconds} -u +%H:%M:%S) # you'll need `brew install coreutils`
    echo "Diff time(H:M:S): $diffTime"
    

    Output:

    BASH_VERSION: 5.0.17(1)-release
    | dates ->  2020-05-21 05:52:47 2020-05-28 19:37:36
    |> startDatetime -> 2020-05-21 05:52:47
    |> endDatetime -> 2020-05-28 19:37:36
    Diff in seconds: 654289
    Diff time(H:M:S): 13:44:49
    

    To install the latest bash I found this medium post.

    Note: If this doesn't work because some version incompatibilities with the date function, for example, the idea should be pretty similar and you could find a workaround that adapts to your current version, I'm sure. Logically, the easiest solution I see is:

    1st) Split the string into two: one for each DateTimes.

    2nd) Transform each DateTime from string to dates.

    3rd) Apply a diff between these dates: using the seconds from each.

    4th) Having the diff seconds you can display it as you want (year, days, minutes, seconds)