#!/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 setglobal date = $[which date] proc daysInMonth { match $1 { with 1|3|5|7|8|10|12 setglobal dim = '31' # most common value with 4|6|9|11 setglobal dim = '30' with 2 setglobal dim = '29' # depending on if it's a leap year with * setglobal dim = '-1' # unknown month } } proc isleap { # returns non-zero value for $leapyear if $1 was a leap year setglobal leapyear = $[$date -d 12/31/$1 +%j | grep 366] } ####################### #### MAIN BLOCK if test $Argc -ne 3 { echo "Usage: $[basename $0] mon day year" echo " with just numerical values (ex: 7 7 1776)" exit 1 } $date --version > /dev/null !2 > !1 # discard error, if any if test $Status -ne 0 { echo "Sorry, but $[basename $0] can't run without GNU date." > !2 ; exit 1 } eval $[$date "+thismon=%m;thisday=%d;thisyear=%Y;dayofyear=%j] setglobal startmon = $1; setglobal startday = $2; setglobal startyear = $3 daysInMonth $startmon # sets global var dim if test $startday -lt 0 -o $startday -gt $dim { echo "Invalid: Month #$startmon only has $dim days." > !2 ; exit 1 } if test $startmon -eq 2 -a $startday -eq 29 { isleap $startyear if test -z $leapyear { echo "$startyear wasn't a leapyear, so February only had 28 days." > !2 exit 1 } } ################################### ## 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 setglobal startdatefmt = ""$startmon/$startday/$startyear"" setglobal calculate = ""$shExpr('10#$($date -d "12/31/$startyear" +%j)') - $shExpr('10#$($date -d $startdatefmt +%j)')"" setglobal daysleftinyear = $shExpr(' $calculate ') ### DAYS IN INTERVENING YEARS setglobal daysbetweenyears = '0' setglobal tempyear = $shExpr(' $startyear + 1 ') while test $tempyear -lt $thisyear { setglobal daysbetweenyears = $shExpr('$daysbetweenyears + $((10#$($date -d "12/31/$tempyear" +%j)))') setglobal tempyear = $shExpr(' $tempyear + 1 ') } ### DAYS IN CURRENT YEAR setglobal dayofyear = $[$date +%j] # that's easy! ### NOW ADD IT ALL UP setglobal totaldays = $shExpr(' $((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