3

I have a two variables :

A= 04.07.2019 23:29:40 and B= 05.07.2019 01:15:52, I want to perform a arithmetic operation C = A - B using bash.

Can some one help me in converting them into integers. In general the dates are different every time, that is why cant neglect the dates.

Output should be in seconds/minutes. If possible in HH:MM:SS format.

  • In what format do you want C? Will seconds be okay? – Soren A Jul 17 at 7:46
  • Yes, it should be in seconds/minutes. – Manoj Kumar Jul 17 at 7:50
  • You can use dateto convert each date to seconds since epoc, subtract them and the convert the resulting seconds back to HH:MM:SS. See man date on howto specify date formats, or convert the date format so that date command understands it natively. – Soren A Jul 17 at 8:02
5

You can use date to convert to timestamp which is seconds, subtract the seconds and then convert back to HH:MM:SS.

Unfortunately, date doesn't read the specified format, so we need to turn around the DD.MM.YYYY to YYYY-MM-DD.

{
A="04.07.2019 23:29:40"
B="05.07.2019 01:15:52"

# Create a function to change DD.MM.YYYY HH:MM:SS to YYYY-MM-DD HH:MM:SS.
convert_date(){ printf '%s-%s-%s %s' ${1:6:4} ${1:3:2} ${1:0:2} ${1:11:8}; }

# Convert to timestamp
A_TS=$(date -d "$(convert_date "$A")" +%s)
B_TS=$(date -d "$(convert_date "$B")" +%s)

# Subtract
DIFF=$((B_TS-A_TS))

# convert to HH:MM:SS (note, that if it's more than one day, it will be wrong!)
TZ=UTC date -d @$DIFF +%H:%M:%S
}

Output:

01:46:12

Using a more general function to subtract the dates:

diff_dates(){
    TS1=$(date -d "$1" +%s)
    TS2=$(date -d "$2" +%s)
    [ $TS2 -ge $TS1 ] \
        && TZ=UTC date -d @$((TS2-TS1)) +%H:%M:%S \
        || TZ=UTC date -d @$((TS1-TS2)) +-%H:%M:%S
}

convert_date(){
    printf '%s-%s-%s %s' ${1:6:4} ${1:3:2} ${1:0:2} ${1:11:8};
}

Usage:

$ A="04.07.2019 23:29:40"
$ B="05.07.2019 01:15:52"
$ diff_dates "$(convert_date "$A")" "$(convert_date "$B")"
01:46:12

or if you already have date-compatible dates:

$ diff_dates "2019-07-04 23:29:40" "2019-07-05 01:15:52"
01:46:12
$ diff_dates "2019-07-05 01:15:52" "2019-07-04 23:29:40"
-01:46:12
  • If possible, can you explain how this line is working: convert_date(){ printf '%d-%d-%d %s' ${1:6:4} ${1:3:2} ${1:0:2} ${1:11:8}; } – Manoj Kumar Jul 17 at 8:28
  • convert_date(){...} creates a function .$1 is the first argument in the function ${1:6:4} is named parameter substitution and will cut 4 characters starting with position 6 => "YYYY" and the others equivalently. '%d-%d-%d %s' is the output format for printf. – pLumo Jul 17 at 8:33
  • Getting this error: > convert_date(){ printf '%d-%d-%d %s' ${1:6:4} ${1:3:2} ${1:0:2} ${1:11:8}; } # Convert to timestamp > TDS_TS=$(date -d "$(convert_date "$TDS")" +%s) > TDE_TS=$(date -d "$(convert_date "$TDE")" +%s) } -bash: printf: 09: invalid octal number date: invalid date ‘2019-7-0 21:44:08’ -bash: printf: 09: invalid octal number date: invalid date ‘2019-7-0 22:06:14’ 01:00:00 – Manoj Kumar Jul 17 at 8:35
  • hm, you might use %s instead of %d, might be it has problems with leading zero, please see my change ?! – pLumo Jul 17 at 8:37
  • 1
    here you go ... now it should be correct. Problem was: date -d @3600 +%H vs TZ=UTC date -d @3600 +%H – pLumo Jul 17 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.