#!	/usr/bin/posix/sh
#
#	Version 1.1.  Gary Katch.
#
#	Calculate date differences.
#
#	Called with 1, 3, 4, or 6 integer arguments.
#	One argument is interpreted as an integer offset to
#	the current date, and the resulting date is printed.
#
#	If called with 3 integers, the arguments are assumed
#	to be year, month, day.  The result is an integer
#	expressing the day offset between the
#	given date and the current date.
#	
#	For more than 3 arguments, the first three arguments
#	specify a base date to be used instead of the current
#	date.
#
#
#	Examples (assuming this shell is called "gdate"):
#
#	Print today's date:
#	  gdate 0
#	What the date will be in 90 days:
#	  gdate 90
#	Print days until author's birthday:
#	  gdate 1956 5 14
#	Print countdown to Y2K:
#	  gdate 2000 1 1
#	Calculate days between arbitrary dates:
#	  gdate y1 m1 d1 y2 m2 d2
#	When that 90-day term deposit will mature:
#	  gdate y1 m1 d1 90
#
self=`basename $0`
typeset -i y m d o g
typeset -f gd gtd
#
function gd {
  typeset -i y=$1 m=$2 d=$3
  (( m=(m+9)%12 ))
  (( y-=m/10 ))
  print -- $(( 365*y+y/4-y/100+y/400+(m*306+5)/10+d-1 ))
  return
  }
#
function gtd {
  typeset -i g=$1
  typeset -i y ddd mi mm dd
  (( y=(10000*g+14780)/3652425 ))
  (( ddd=g-(365*y+y/4-y/100+y/400) ))
  [[ $ddd -lt 0 ]] && {
    (( y-=1 ))
    (( ddd=g-(365*y+y/4-y/100+y/400) ))
    }
  (( mi=(100*ddd+52)/3060 ))
  (( mm=(mi+2)%12+1 ))
  (( y+=(mi+2)/12 ))
  (( dd=ddd-(mi*306+5)/10+1 ))
  print -- $y $mm $dd
  return
  }
#
function legald {
  typeset -i g y=$1 m=$2 d=$3
  (( g = `gd $y $m $d` ))
  if [[ "`gtd $g`" = "$y $m $d" ]] ; then
    print -- $g
  else
    print -- "-1"
  fi
  return
  }

test "$SHDEBUG" && set -x
argc=$#
args="$*"
if [[ $argc -gt 3 ]] ; then
  (( g = `legald $1 $2 $3` ))
  [[ $g -lt 0 ]] && {
    print -- "Illegal date: $1 $2 $3" 1>&2
    exit 1
    }
  shift; shift; shift
  args="$*"
  (( argc -= 3 ))
else
  set -- `date +"%Y %m %d"`
  (( g = `gd $1 $2 $3` ))
  fi
if [[ $argc -eq 1 ]] ; then 
  set  -- $args
  gtd $(( g += $1 ))
elif [[ $argc -eq 3 ]] ; then
  set -- $args
  (( h = `legald $1 $2 $3` ))
  if [[ $h -lt 0 ]] ; then
    print -- "Illegal date: $1 $2 $3" 1>&2
    exit 1
    fi
  print -- $(( g - h ))
else
  print "Usage: $self [y m d] [[n] | [y m d]]"
fi
#