#!/usr/bin/bash

# yyd - generates a year and yearday (yyyyjjj) filedate <daysback>
# days from <mm/yy/dd>. The default is 0 days from the current date.

# Copyright (C) 2004 MBARI
# Author: Kent Headley
# MBARI provides this documentation and code "as is", with no warranty,
# express or implied, of its quality or consistency. It is provided without
# support and without obligation on the part of the Monterey Bay Aquarium
# Research Institute to assist in its use, correction, modification, or
# enhancement. This information should not be published or distributed to
# third parties without specific written permission from MBARI.


# function isleap(year)
# Tests whether or not year is a leap year
# argument: 4 digit year
# returns: 1 if year is a leap year, 0 otherwise
isleap(){
let foo="$1 % 4"
let bar="$1 % 100"
let baz="$1 % 400"
if [ "$foo" -eq 0 ] && [ "$bar" -ne 0 -o  "$baz"  -eq 0  ]
then
return 1
else
return 0
fi
}

# function usage()
# Prints use message to console and exits
# arguments: none
# returns: none
usage(){
echo
echo "Generates year and yearday (yyyyjjj) period"
echo "days before startdate"
echo
echo "Usage $0 [-hvd <startdate> -p <period>]"
echo
echo "-h              Display this help message"
echo "-v              Enable verbose output [no verbose output]"
echo "-p <period>     Days before start date [0]"
echo "-d <startdate>  Start date [current date]"
echo 
echo "Examples:"
echo
echo "Generate year and year day for date 60 days before today:"
echo "$0 -p 60"
echo
echo "Generate year and year day for today:"
echo "$0"
echo
echo "Generate year and year day for date 30 days before May 27, 1998 [1998117]:"
echo "$0 -p 30 -d 5/27/1998"
echo
echo "Generate year and year day for date 731 days before Jan 1, 2001 [1999001]:"
echo "$0 -p 731 -d 1/1/2001"
echo

exit 1
}

# Set default values
datestr=`date +%m/%d/%Y`
daysback=0
verbose=0

# Process command line
while getopts "d:hp:v" Option 
do
   case $Option in
   [d] ) 
	    datestr="$OPTARG"
    ;;
   [p] ) 
	    let daysback="$OPTARG"
    ;;
   [v] ) 
	    verbose=1
    ;;
   [h] ) 
	    usage
    ;;
    * ) echo unrecognized option 
    ;;
    esac
done

# override defaults
let fromyr=`date +%Y -d $datestr`
let fromyd=`date +%-j -d $datestr`

if [ "$verbose" -ne 0 ]
then
echo datestr $datestr fromyd $fromyd  daysback $daysback 
fi

# Must start from day before specified yearday
# because by convention, we always start at 
# fromyd and count backwards, inclusive
let fromyd="$fromyd-1"

if [ "$verbose" -ne 0 ]
then
echo fromyr $fromyr fromyd $fromyd daysback $daysback
fi

# Loop until daysback is less than fromyd.
# Note that it doesn't execute this if
# we are going back less than fromyd days

while [ "$daysback" -ge "$fromyd" ]
do
 
 # set year to previous year
 let fromyr="$fromyr-1"
 
 # test if year is leapyear
 isleap $fromyr
 let leap="$?"

 # compute number of days remaining
 let daysback="$daysback-$fromyd"

 # if year is a leap year,
 # we start counting at day 366
 # else start at day 365
 if [ "$leap" -eq 1 ]
 then
  if [ "$verbose" -ne 0 ]
  then
   echo $fromyr IS a leap year
   echo days in $fromyr: 366
  fi
  let fromyd=366  
 else
  if [ "$verbose" -ne 0 ]
  then
   echo $fromyr IS NOT a leap year
   echo days in $fromyr: 365
  fi
  let fromyd=365 
 fi

  if [ "$verbose" -ne 0 ]
  then
   echo fromyr $fromyr fromyd: $fromyd daysback $daysback
  fi

 # if days remaining is less than start date
 # we are done
 if [ "$daysback" -lt "$fromyd" ] 
 then
   
 # if daysback is zero, go forward one day
 # otherwise, subtract days remaining from
 # start day.
 # Notes: 
 # - yeardays are numbered from 1
 # - the startday is included in our counting
 if [ "$daysback" -eq 0 ]
 then
  let yd=1
  let yr="$fromyr+1"
 else
  let yd="$fromyd-$daysback+1"
  let yr="$fromyr"
 fi
   # send output to console (yyyyjjj)
   echo $yr`printf "%03d" $yd`
   exit 0
 fi


done

# The daysback is less than the start day
# so the day will fall in the current year
# Notes: 
# - yeardays are numbered from 1
# - the startday is included in our counting

let yd="$fromyd-$daysback+1"
let yr="$fromyr"

# send output to console (yyyyjjj)
echo $yr`printf "%03d" $yd`

exit 0
