#!/bin/bash
# Skrypt daysago określający liczbę dni, jakie upłynęły od podanej daty
# w przeszłości do dzisiaj, z uwzględnieniem lat przestępnych.

# Jeżeli korzystasz z systemu Linux, poniższa zmienna musi zawierać ciąg `which date`.
# Jeżeli korzystasz z systemu macOS, zainstaluj za pomocą polecenia brew pakiet
# coreutils.
date="`which date`"
#date="$(which gdate)"

function daysInMonth
{
  case $1 in
    1|3|5|7|8|10|12 ) dim=31 ;;  # Najczęstsza wartość.
    4|6|9|11        ) dim=30 ;;
    2               ) dim=29 ;;  # Wartość zależna od tego, czy rok jest przestępny.
    *               ) dim=-1 ;;  # Nieznany numer miesiąca.
  esac
}

function isleap
{
  # Funkcja przypisująca zmiennej $leapyear wartość różną od zera, jeżeli rok podany
  # w argumencie $1 jest rokiem przestępnym.
  leapyear=$($date -d 12/31/$1 +%j | grep 366)
}

######################
#### GŁÓWNA CZĘŚĆ KODU

if [ $# -ne 3 ] ; then
  echo "Użycie: $(basename $0) dzień miesiąc rok"
  echo "Data wyrażona za pomocą liczb (np. 3 5 1791 )."
  exit 1
fi

$date --version > /dev/null 2>&1         # Ukrycie ewentualnych komunikatów o błędach.

if [ $? -ne 0 ] ; then
  echo "Niestety, skrypt $(basename $0) nie działa bez polecenia date GNU." >&2 ; exit 1
fi

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

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

daysInMonth $startmon # Nadanie wartości globalnej zmiennej dim.

if [ $startday -lt 0 -o $startday -gt $dim ] ; then
  echo "Błąd: miesiąc $startmon ma $dim dni." >&2 ; exit 1
fi

if [ $startmon -eq 2 -a $startday -eq 29 ] ; then
  isleap $startyear
  if [ -z "$leapyear" ] ; then
    echo "Błąd: rok $startyear nie był rokiem przestępnym, więc luty miał 28 dni." >&2
    exit 1
  fi
fi

########################
## OKREŚLENIE LICZBY DNI
########################

### OKREŚLENIE LICZBY DNI W ROKU POCZĄTKOWYM.

# Przygotowanie ciągu znaków reprezentującego datę początkową.

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

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

daysleftinyear=$(( $calculate ))

### OKREŚLENIE LICZBY DNI W KAŻDYM MINIONYM ROKU.

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

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

### OKREŚLENIE LICZBY DNI W BIEŻĄCYM ROKU.

dayofyear=$($date +%j) # To proste!

### ZSUMOWANIE WSZYSTKICH WARTOŚCI.

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

echo -n "Od dnia $startyear-$startmon-$startday "
echo -n "do dzisiaj, $((10#$dayofyear)) dnia roku $thisyear, "
echo "upłynęło $totaldays dni."
exit 0
