#!/bin/bash
# daysago -- given a date in the form month/day/year, calculate how many
#     days in the past that was, factoring in leap years, etc.

# If you are on Linux, this should only be `which date`
# If you are on OS X, install coreutils with brew or from source for gdate
date="`which date`"  

function daysInMonth
{
  case $1 in
    1|3|5|7|8|10|12 ) dim=31 ;; # most common value
    4|6|9|11        ) dim=30 ;;
    2               ) dim=29 ;;  # depending on if it's a leap year
    *               ) dim=-1 ;;  # unknown month
  esac
}

function isleap
{
  # returns non-zero value for $leapyear if $1 was a leap year 
    leapyear=$($date -d 12/31/$1 +%j | grep 366)
}

#######################
#### MAIN BLOCK

if [ $# -ne 3 ] ; then
  echo "Usage: $(basename $0) mon day year"
  echo "  with just numerical values (ex: 7 7 1776)"
  exit 1
fi

$date --version > /dev/null 2>&1         # discard error, if any

if [ $? -ne 0 ] ; then
  echo "Sorry, but $(basename $0) can't run without GNU date." >&2 ; exit 1
fi

eval $($date "+thismon=%m;thisday=%d;thisyear=%Y;dayofyear=%j")

startmon=$1; startday=$2; startyear=$3

daysInMonth $startmon # sets global var dim

if [ $startday -lt 0 -o $startday -gt $dim ] ; then
  echo "Invalid: Month #$startmon only has $dim days." >&2 ; exit 1
fi

if [ $startmon -eq 2 -a $startday -eq 29 ] ; then
  isleap $startyear
  if [ -z "$leapyear" ] ; then
    echo "$startyear wasn't a leapyear, so February only had 28 days." >&2
    exit 1
  fi
fi

###################################
## part two: the number of days since the day you specify.
###################################

###  FIRST, DAYS LEFT IN START YEAR

# calculate the date string format for the specified starting date

startdatefmt="$startmon/$startday/$startyear"

calculate="$((10#$($date -d "12/31/$startyear" +%j))) - $((10#$($date -d $startdatefmt +%j)))"

daysleftinyear=$(( $calculate ))

###  DAYS IN INTERVENING YEARS

daysbetweenyears=0
tempyear=$(( $startyear + 1 ))

while [ $tempyear -lt $thisyear ] ; do
  daysbetweenyears=$(($daysbetweenyears + $((10#$($date -d "12/31/$tempyear" +%j)))))
  tempyear=$(( $tempyear + 1 ))
done

###   DAYS IN CURRENT YEAR

dayofyear=$($date +%j) # that's easy!

###   NOW ADD IT ALL UP

totaldays=$(( $((10#$daysleftinyear)) + $((10#$daysbetweenyears)) + $((10#$dayofyear)) ))

/bin/echo -n "$totaldays days have elapsed between $startmon/$startday/$startyear "
echo "and today, day $dayofyear of $thisyear."
exit 0
