Simple date and time calulation in BASH

There is a closed Thread: <url>Here will be the url to the original post once I have 5 posts in this forum...</url>

But a small bug had found his way into this very cool and simple code.

#!/bin/bash  date2stamp () {     date --utc --date "$1" +%s }  stamp2date (){     date --utc --date "1970-01-01 $1 sec" "+%Y-%m-%d %T" }  dateDiff (){     case $1 in         -s)   sec=1;      shift;;         -m)   sec=60;     shift;;         -h)   sec=3600;   shift;;         -d)   sec=86400;  shift;;         *)    sec=86400;;     esac     dte1=$(date2stamp $1)     dte2=$(date2stamp $2)     diffSec=$((dte2-dte1))     if ((diffSec < 0)); then abs=-1; else abs=1; fi     echo $((diffSec/sec*abs)) }  # USAGE # # # # # # # # # # # # # # # # # # # # # # # # # # # # #   # convert a date into a UNIX timestamp     stamp=$(date2stamp "2006-10-01 15:00")     echo $stamp  # from timestamp to date     stamp2date $stamp  # calculate the number of days between 2 dates     # -s in sec. | -m in min. | -h in hours  | -d in days (default)     dateDiff -s "2006-10-01" "2006-10-32"     dateDiff -m "2006-10-01" "2006-10-32"     dateDiff -h "2006-10-01" "2006-10-32"     dateDiff -d "2006-10-01" "2006-10-32"     dateDiff  "2006-10-01" "2006-10-32"  # number of seconds between two times     dateDiff -s "17:55" "23:15:07"     dateDiff -m "17:55" "23:15:07"     dateDiff -h "17:55" "23:15:07"  # number of minutes from now until the end of the year     dateDiff -m "now" "2006-12-31 24:00:00 CEST"  # Other standard goodies from GNU date not too well documented in the man pages     # assign a value to the variable dte for the examples below     dte="2006-10-01 06:55:55"     echo $dte      # add 2 days, one hour and 5 sec to any date     date --date "$dte  2 days 1 hour 5 sec"      # substract from any date     date --date "$dte 3 days 5 hours 10 sec ago"     date --date "$dte -3 days -5 hours -10 sec"      # or any mix of +/-. What will be the date in 3 months less 5 days     date --date "now +3 months -5 days"      # time conversions into ISO-8601 format (RFC-3339 internet recommended format)     date --date "sun oct 1 5:45:02PM" +%FT%T%z     date --iso-8601=seconds --date "sun oct 1 5:45:02PM"     date --iso-8601=minutes      # time conversions into RFC-822 format     date --rfc-822 --date "sun oct 1 5:45:02PM"

Here is a diff to see what's different:

--- timediff.sh 2013-02-28 08:37:10.097782308 +0100
+++ timediff-new.sh     2013-02-28 08:37:39.135777585 +0100
@@ -16,8 +16,8 @@
         -d)   sec=86400;  shift;;
         *)    sec=86400;;
     esac
-    dte1=$(date2stamp $1)
-    dte2=$(date2stamp $2)
+    dte1=$(date2stamp "$1")
+    dte2=$(date2stamp "$2")
     diffSec=$((dte2-dte1))
     if ((diffSec < 0)); then abs=-1; else abs=1; fi
     echo $((diffSec/sec*abs))

The Problem:

Calling the dateDiff function as follows results in an incorrect calculation:

 dateDiff -h "now" "2013-02-28 08:02:31"

Withing the dateDiff function the date and time will be ok, but forwarding this timestamp to the function date2stamp will not work like expected:

 date2stamp 2013-02-28 08:02:31

against

 date2stamp "2013-02-28 08:02:31"

I hope to help people who are using this code. :wink:

greetings
frood

Bash does not have everything: Korn Shell 93 Date/Time String Manipulation and Arithmetic

I'd also note that this isn't a pure bash script exactly, it depends on GNU date.

And if you've got GNU date you've got simple date arithmetic anyway...