Reputation: 203
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"
Upvotes: 10
Views: 19606
Reputation: 19223
when the datetime string is printed on each line and you need millisecond or microsecond time delta i use python:
placeholder | sed 's/.*\(regex\).*/\1/g' | python3 -c "
import datetime
import sys
contents = sys.stdin.read().strip()
lines = contents.splitlines()
# remove nanoseconds and 'Z'
lines = [line[:-4] for line in lines]
fmt = '%Y-%m-%dT%H:%M:%S.%f'
dtimes = [datetime.datetime.strptime(line) for line in lines]
deltas = [(dt1 - dt0) in zip(dtimes[1:], dtimes[0:-1])]
import pprint
pprint.pprint(deltas)
"
Upvotes: 0
Reputation: 647
Same version as @chemaclass but this time for Ubuntu (16.04 LTS).
#!/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 -d "${startDatetime}" +%s)
endTime=$(date -d "${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=$(date -d @${diffSeconds} +"%H:%M:%S" -u)
echo "Diff time(H:M:S): $diffTime"
Output:
BASH_VERSION: 5.0.0(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
I updated the bash to version 5.0.0 following this tutorial.
With the default bash version (4.4.20) doesn't work.
You will get an error message like: redirection unexpected
on line 3 because of the <<<
symbol.
Upvotes: 5
Reputation: 2011
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)
Upvotes: 9
Reputation: 12008
A possible approach could be
#!/bin/bash
strSTARTTIME="2020-05-21 05:52:47"
strENDTIME="2020-05-28 19:37:36"
STARTTIME=$(date -d "${strSTARTTIME}" +%s)
ENDTIME=$(date -d "${strENDTIME}" +%s)
RUNTIME=$((ENDTIME-STARTTIME))
echo "Seconds ${RUNTIME} in sec"
Further calculation and formatting I'll leave at your side.
Upvotes: 2