Date functions: eday


eday() #@ Get day number since the epoch (1970-01-01 = 1)
{      #@ USAGE: eday YYYY-MM-DD[THH:MM:SS] [VAR]
       #@ REQUIRES: bash4.3, is_leap_year(), vshow()
  ((debug)) && set -x
  local date=$1 _var=$2 eyear=1970 IFS=$' \t\n'
  local eday1=${eday1:-1} ## default: 1970-01-01 = day 1
  local year month day junk years days eday
  local m1=( 0 0 31 59 90 120 151 181 212 243 273 304 334 )
  if [[ -z $date ]]
  then
    printf -v year  '%(%Y)T'
    printf -v month '%(%m)T'
    printf -v day   '%(%d)T'
  else
    read year month day junk <<< "${date//[!0-9]/ }"
  fi
vshow date year  month day
  (( year < eyear )) && return 1
  month=${month#0}
  day=${day#0}
  years=$(( year - eyear ))
  eday=$(( years * 365 + (years + 1) / 4 + m1[month] + day - (eday1 == 0) ))
  (( month > 2 )) && is_leap_year "$year" && ((++eday))
  ((verbose)) && vshow year month day date years eday
  [[ ${_var^^} =~ ^[A-Z_][A-Z0-9_]*$ ]] &&
    printf -v "$_var" '%d' "$eday" ||
      printf '%d\n' "$eday"
  ((debug==1)) && set +x
}