I have two date/time values in yyyymmddhhmmss format in shell variables.
I want to subtract one from the other and get the result in seconds like below:


The result I want is c=1 (because 02:00:00 is one second later than 01:59:59), but I got c=4041.

How can I subtract date/time values to have result in seconds?

closed as unclear what you're asking by Jeff Schaller, Stephen Rauch, countermode, Archemar, αғsнιη Aug 4 '17 at 9:35

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • @JeffSchaller i didnt get you well – Ammar Akkad Aug 3 '17 at 23:33
  • @JeffSchaller mi is minute and i want the diff to be in second not as a decimal number – Ammar Akkad Aug 3 '17 at 23:35
  • Please demonstrate how you are currently subtracting and how you want it to be different. – Jeff Schaller Aug 3 '17 at 23:39
  • @JeffSchaller i want to change the type to date then diff do you have any idea how to do that – Ammar Akkad Aug 3 '17 at 23:39
  • 1
    Convert time to unix time before substraction? Result gives you the difference in seconds (which can be converted to desired units). This would be simpler with different programming environment to shell imo. – sebasth Aug 3 '17 at 23:45

First you need to convert the dates to unix time_t format (i.e. seconds since the "epoch", 1970-01-01 00:00:00). Then you can calculate the difference with a simple subtraction.

The dates you have are not understood by the date program in their current format. It expects something that looks more like a date with dashes and colons separating the fields than a number.

Here's an example that uses sed in a function to "fix" the dates - i.e. convert them to a format understood by date, then uses date to convert to time_t seconds, then do the subtraction:



function fixdate() {
  printf "$1" | sed -E -e 's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/'

a_seconds="$(date -d "$(fixdate "$a")" '+%s')"
b_seconds="$(date -d "$(fixdate "$b")" '+%s')"
seconds=$((a_seconds - b_seconds))

echo "$seconds"
  • 1
    btw, the fixdate function definition isn't necessary. I wrote it this way because: 1. "DRY" or "Don't Repeat Yourself" - if you find yourself doing the same thing repeatedly, turn it into a function or subroutine. 2. it's a lot more readable this way. 3. i hate horizontal scroll bars, especially when reading code. – cas Aug 4 '17 at 2:18
  • I think he downvoted it because he doesn't understand it. – Jesse_b Aug 4 '17 at 2:32
  • Oh btw you missed the bang in your #! – Jesse_b Aug 4 '17 at 11:03
  • actually i am new to unix and i didn't know how to build a function thanks m8 you helped a lot :) – Ammar Akkad Aug 5 '17 at 12:57

It's not pretty but this worked for me in centos:





adate=$(date -d "$amonth/$aday/$ayear $ahour:$amin:$asec" +"%s")
bdate=$(date -d "$bmonth/$bday/$byear $bhour:$bmin:$bsec" +"%s")
  • 2
    this could be a lot shorter using sed to transform the dates to a format understood by the date program, e.g. adate="$(date -d "$(printf "$a" | sed -E -e 's/(....)(..)(..)(..)(..)(..)/\1-\2-\3 \4:\5:\6/')" '+%s')" – cas Aug 4 '17 at 1:58

You can do math operations with dates by converting them in Unix format. But for do that, first you'll need to give those values (yyyymmddhhmmss) some proper format (yyyy-mm-dd hh:mm:ss).

Then you could do something like:

$ a=$(date -d '2017-08-04 02:00:00' '+%s')
$ b=$(date -d '2017-08-04 01:59:59' '+%s')
$ c=$((a-b))
$ echo $a
$ echo $b
$ echo $c
  • 1
    This is just my answer without actually being an answer at all. – Jesse_b Aug 4 '17 at 2:30

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