Bash: calculate the time elapsed between two timestamps
Solution 1
This will give you the date in seconds (since the UNIX epoch)
date --date '2017-08-17 04:00:01' +%s # "1502938801"
And this will give you the date as a readable string from a number of seconds
date --date '@1502938801' # "17 Aug 2017 04:00:01"
So all that's needed is to convert your date/timestamp into a format that GNU date
can understand, use maths to determine the difference, and output the result
datetime1=20170817040001
datetime2=20160312000101
# bash string manipulation
datestamp1="${datetime1:0:4}-${datetime1:4:2}-${datetime1:6:2} ${datetime1:8:2}:${datetime1:10:2}:${datetime1:12:2}"
datestamp2="${datetime2:0:4}-${datetime2:4:2}-${datetime2:6:2} ${datetime2:8:2}:${datetime2:10:2}:${datetime2:12:2}"
# otherwise use sed
# datestamp1=$(echo "$datetime1" | sed -nr 's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/p')
# datestamp2=$(echo "$datetime2" | sed -nr 's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/p')
seconds1=$(date --date "$datestamp1" +%s)
seconds2=$(date --date "$datestamp2" +%s)
delta=$((seconds1 - seconds2))
echo "$delta seconds" # "45197940 seconds"
We've not provided timezone information here so it assumes local timezone. Your values for the seconds from the datetime will probably be different to mine. (If your values are UTC then you can use date --utc
.)
Solution 2
This is easy with datediff
command provided in dateutils
package.
ddiff -i '%Y%m%d%H%M%S' 20170817040001 20160312000101
Related videos on Youtube
Marco
Updated on September 18, 2022Comments
-
Marco over 1 year
I have written a script that notifies me when a value is not within a given range. All values "out of range" are logged in a set of per day files.
Every line is timestamped in a proprietary reverse way: yyyymmddHHMMSS
Now, I would like to refine the script, and receive notifications just when at least 60 minutes are passed since the last notification for the given out of range value.
I already solved the issue to print the logs in reverse ordered way with:
for i in $(ls -t /var/log/logfolder/*); do zcat $i|tac|grep \!\!\!|grep --color KEYFORVALUE; done
that results in:
... 20170817041001 - WARNING: KEYFORVALUE=252.36 is not between 225 and 245 (!!!) 20170817040001 - WARNING: KEYFORVALUE=254.35 is not between 225 and 245 (!!!) 20170817035001 - WARNING: KEYFORVALUE=254.55 is not between 225 and 245 (!!!) 20170817034001 - WARNING: KEYFORVALUE=254.58 is not between 225 and 245 (!!!) 20170817033001 - WARNING: KEYFORVALUE=255.32 is not between 225 and 245 (!!!) 20170817032001 - WARNING: KEYFORVALUE=254.99 is not between 225 and 245 (!!!) 20170817031001 - WARNING: KEYFORVALUE=255.95 is not between 225 and 245 (!!!) 20170817030001 - WARNING: KEYFORVALUE=255.43 is not between 225 and 245 (!!!) 20170817025001 - WARNING: KEYFORVALUE=255.26 is not between 225 and 245 (!!!) 20170817024001 - WARNING: KEYFORVALUE=255.42 is not between 225 and 245 (!!!) 20170817012001 - WARNING: KEYFORVALUE=252.04 is not between 225 and 245 (!!!) ...
Anyway, I'm stuck at calculating the number of seconds between two of those timestamps, for instance:
20170817040001 20160312000101
What should I do in order to calculate the time elapsed between two timestamps?
-
111--- almost 7 yearsAre you looking for time delta expressed in a particular format, I.E. "HH:MM:SS"? Also, why not just log UNIX timestamps?
-
jesse_b almost 7 yearsThis question should help you solve this issue: unix.stackexchange.com/questions/383795/…
-
Marco almost 7 years@roaima Ubuntu Linux. I expect the script to work in any GNU Linux.
-
Marco almost 7 years@datUser for ease of use (I'll have to make calculations on this delta) seconds would be nice.
-
111--- almost 7 years@Marco then if you are writing the script I would consider adding a timestamp column and save some awkward bash scripting to do the math from a datetime value. Not trying to be snarky here, honest suggestion. Then math is a breeze.
-
Marco almost 7 years@datUser I already have logs that I'd like to keep. I should find a way to automatically calculate the unix timestamp from my custom one, and batchly edit the logs.
-
jesse_b almost 7 years@Marco see the link in my comment for several ways to calculate the unix timestamp.
-
Marco almost 7 years@Jesse_b found it, TY!
-
jesse_b almost 7 yearsOh I also just noticed you are parsing ls in your script. You shouldn't do this. You can do
for i in "/var/log/logfolder/*";
instead. mywiki.wooledge.org/ParsingLs -
Marco almost 7 years@Jesse_b, with your for, how would I ensure I'm reading files in the right reversed time order? I don't know how to, and that's why I use to use ls when I work in folders just containing properly formatted filenames.
-
jesse_b almost 7 yearsYou can try to put it in a subshell and pipe it into sort.
$(find /var/log/logfolder -type f -name "*" | sort -n)
maybe? -
roaima almost 7 years@Jesse_b that's not really any different to using
ls -t
; you're still parsing the output of a command that generates a list of filenames. (Oh,-name "*"
is almost a no-op; you wouldn't need it here. And how wouldsort -n
be able to sort file names numerically?) -
jesse_b almost 7 yearsI dunno...Hence why I said I didn't know.
-
-
Marco almost 7 yearsWhen I started writing this post, I was almost sure it would have ended with sed doing the dirty job. TY @roaima
-
Marco almost 7 yearsthis on ubuntu 16.04 LTS
user@host:/~# apt-get install dateutils [...] Setting up dateutils (0.2.5-1) ... user@host:/~# datediff datediff: command not found user@host:/~#
-
αғsнιη almost 7 yearssorry, the command-line command is
ddiff
-
MatsK almost 7 yearsOr dateutils.ddiff
-
Marco almost 7 yearsThis solution is very intresting too, but I keep the
sed
one in my script; as I find it's most compatible with any GNU Linux and saves me one more dependency. -
Marco almost 7 yearsAlso, please note that the correct name for this command in Linux Ubuntu 16.04 is
dateutils.ddiff
-
Scott - Слава Україні about 4 yearsCome on, think about it. For simplicity, look at only HHMMSS (assume two entries from the same day). What’s the elapsed time between 12:00:00 and 12:01:00? It’s one minute; i.e., 60 seconds. But 120100−120000 is 100.
-
Marco about 4 yearsObviously he didn't read the question because the main point is exactly getting rid of this customized timestamp. BTW after years I want to inform people that I solved the problem switching to a Unix timestamp, it is not as human readable as this custom one, but you'd better write a log parser script that shows you date in human readable form and let the system work on its own true low level time handling (seconds elapsed since 1/1/70).
-
ychaouche over 3 yearsAnyway I can use
dateutils.ddiff
to compute the difference between two time durations ?