I print the start and end time using date +"%T"
, which results in something like:
10:33:56
10:36:10
How could I calculate and print the difference between these two?
I would like to get something like:
2m 14s
I print the start and end time using date +"%T"
, which results in something like:
10:33:56
10:36:10
How could I calculate and print the difference between these two?
I would like to get something like:
2m 14s
Another option is to use
datediff
fromdateutils
(http://www.fresse.org/dateutils/#datediff):You could also use
gawk
.mawk
1.3.4 also hasstrftime
andmktime
but older versions ofmawk
andnawk
don't.Or here's another way to do it with GNU
date
:Seconds
To measure elapsed time (in seconds) we need:
An integer value of elapsed seconds:
There are two bash internal ways to find an integer value for the number of elapsed seconds:
Bash variable SECONDS (if SECONDS is unset it loses its special property).
Setting the value of SECONDS to 0:
Storing the value of the variable
SECONDS
at the start:Bash printf option
%(datefmt)T
:Convert such integer to an usable format
The bash internal
printf
can do that directly:similarly
but this will fail for durations of more than 24 hours, as we actually print a wallclock time, not really a duration:
For the lovers of detail, from bash-hackers.org:
So you may want to just call
textifyDuration $elpasedseconds
wheretextifyDuration
is yet another implementation of duration printing:GNU date.
To get formated time we should use an external tool (GNU date) in several ways to get up to almost a year length and including Nanoseconds.
Math inside date.
There is no need for external arithmetic, do it all in one step inside
date
:Yes, there is a
0
zero in the command string. It is needed.That's assuming you could change the
date +"%T"
command to adate +"%s"
command so the values will be stored (printed) in seconds.Note that the command is limited to:
$StartDate
and$FinalDate
seconds.$FinalDate
is bigger (later in time) than$StartDate
.If you must use the
10:33:56
string, well, just convert it to seconds,also, the word seconds could be abbreviated as sec:
Note that the seconds time conversion (as presented above) is relative to the start of "this" day (Today).
The concept could be extended to nanoseconds, like this:
If is required to calculate longer (up to 364 days) time differences, we must use the start of (some) year as reference and the format value
%j
(the day number in the year):Similar to:
Sadly, in this case, we need to manually subtract
1
ONE from the number of days. The date command view the first day of the year as 1. Not that difficult ...The use of long number of seconds is valid and documented here:
https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html#Examples-of-date
Busybox date
A tool used in smaller devices (a very small executable to install): Busybox.
Either make a link to busybox called date:
Use it then by calling this
date
(place it in a PATH included directory).Or make an alias like:
Busybox date has a nice option: -D to receive the format of the input time. That opens up a lot of formats to be used as time. Using the -D option we can convert the time 10:33:56 directly:
And as you can see from the output of the Command above, the day is assumed to be "today". To get the time starting on epoch:
Busybox date can even receive the time (in the format above) without -D:
And the output format could even be seconds since epoch.
For both times, and a little bash math (busybox can not do the math, yet):
Or formatted:
date
can give you the difference and format it for you (OS X options shown)Some string processing can remove those empty values
This won't work if you place the earlier time first. If you need to handle that, change
$(($(date ...) - $(date ...)))
to$(echo $(date ...) - $(date ...) | bc | tr -d -)
Here is a solution using only the
date
commands capabilities using "ago", and not using a second variable to store the finish time:this gives:
Or wrap it up a bit
Then this works.