Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find difference between two dates in bash

Tags:

date

bash

I attempted to get the difference between two dates with:

date -d $(echo $(date -d "Sun Dec 29 02:22:19 2013" +%s) - $(date -d "Sun Dec 28 03:22:19 2013" +%s) | bc)

However, this returns

date: invalid date ‘82800’

Why is this, and how can I get the desired result?

like image 868
gandalf3 Avatar asked Dec 30 '13 00:12

gandalf3


People also ask

How do you find the difference between two dates in Unix shell script?

First, calculate convert the dates to be compared into unix timestamps: date1=$(date --date="2020-10-31 05:41:33" "+%s") date2=$(date --date="2020-11-01 05:41:33" "+%s")

How does bash calculate dates?

To get the date in bash shell and add a date, you can use the GNU date command as date -d 'Feb 12 +1 day' +%F which will output 2020-02-13 . See the above section on GNU date for more examples on the -d option.

What is let in bash?

Bash let is a built-in command in Linux systems used for evaluating arithmetic expressions. Unlike other arithmetic evaluation and expansion commands, let is a simple command with its own environment. The let command also allows for arithmetic expansion.


1 Answers

You can use:

date1="Sat Dec 28 03:22:19 2013"
date2="Sun Dec 29 02:22:19 2013"
date -d @$(( $(date -d "$date2" +%s) - $(date -d "$date1" +%s) )) -u +'%H:%M:%S'

And the output is:

23:00:00

However, for arbitrary differences over 24 hours, you have to start worrying about how the value for days will be represented. Negative values will also present problems.

The problem with this is that if you drop the format string, the date presented is:

Thu Jan  1 23:00:00 UTC 1970

So, while this works for the two given date/time values, it is not really a general solution.

Consider adding %j for the day of year; it will work semi-sanely for up to 1 year's difference.

Otherwise, capture the difference in a variable and present the results with a separate calculation.

date1="Sat Dec 28 03:22:19 2013"
date2="Sun Dec 29 02:22:19 2013"
delta=$(( $(date -d "$date2" +%s) - $(date -d "$date1" +%s) ))
if [[ $delta -lt 0 ]]
then sign="-"; delta=${delta/^-/}
else sign="+"
fi
ss=$(( $delta % 60 ))
delta=$(( $delta / 60 ))
mm=$(( $delta % 60 ))
delta=$(( delta / 60 ))
hh=$(( $delta % 24 ))
dd=$(( $delta / 24 ))
printf "$sign%d %.2d:%.2d:%.2d\n" $dd $hh $mm $ss

Output:

+0 23:00:00

(Meaning: a positive difference of 0 days, 23 hours, 0 minutes, 0 seconds.) Splitting a number of days such as 1000 into years, months and days is fraught without any reference dates. Here, there are reference dates to help, but it would still be ... fun.

like image 147
Jonathan Leffler Avatar answered Sep 27 '22 20:09

Jonathan Leffler