#!/bin/sh
# valid-date -- Valide une date, en prenant en compte les annes
#   bissextiles.

exceedsDaysInMonth()
{
  # tant donn un nom de mois, renvoie 0 si la valeur spcifie 
  # pour le jour est infrieure ou gale au nombre maximal de jours
  # dans ce mois; renvoie 1 dans le cas contraire.

  case $(echo $2|tr '[:upper:]' '[:lower:]') in
    jan* ) days=31     ;;  fev* ) days=28     ;;
    mar* ) days=31     ;;  avr* ) days=30     ;;
    mai* ) days=31     ;;  jun* ) days=30     ;;
    jul* ) days=31     ;;  aou* ) days=31     ;;
    sep* ) days=30     ;;  oct* ) days=31     ;;
    nov* ) days=30     ;;  dec* ) days=31     ;;
    * ) echo "$0: Nom de mois inconnu $2" >&2; exit 1 
  esac

  if [ $1 -lt 1 -o $1 -gt $days ] ; then 
    return 1 
  else 
    return 0    # le numro du jour est valide
  fi 
}

isLeapYear() {
  # Cette fonction renvoie 0 si l'anne est bissextile; 1 sinon.

  # Formule pour savoir si une anne est bissextile:
  # 1. Les annes non divisibles par 4 ne sont pas bissextiles.
  # 2. Les multiples de 4 et de 400 sont bissextiles.
  # 3. Les multiples de 4 et de 100 mais pas de 400 ne sont pas bissextiles. 
  # 4. Tous les autres multiples de 4 sont bissextiles.

  year=$1 
  if [ "$((year % 4))" -ne 0 ] ; then  
    return 1 # non, pas une anne bissextile
  elif [ "$((year % 400))" -eq 0 ] ; then  
    return 0 # oui, c'est une anne bissextile 
  elif [ "$((year % 100))" -eq 0 ] ; then  
    return 1 
  else  
    return 0 
  fi 
}

## Dbut du script principal

if [ $# -ne 3 ] ; then 
  echo "Syntaxe: $0 jour mois anne" >&2 
  echo "Exemples: 3 Aout 1962 et 3 8 2002" >&2 
  exit 1
fi

# Normalise la date et dcoupe les valeurs renvoyes

newdate="$(normdate "$@")"

if [ $? -eq 1 ] ; then 
  exit 1   # condition d'erreur dj dtaille par normdate
fi

month="$(echo $newdate | cut -d\  -f2)" 
day="$(echo $newdate | cut -d\  -f1)" 
year="$(echo $newdate | cut -d\  -f3)"

# Maintenant que nous disposons d'une date normalise, voyons si la
# valeur du jour est valable.

if ! exceedsDaysInMonth "$1" $month ; then 
  if [ "$month" = "Fev" -a "$1" -eq "29" ] ; then
    if ! isLeapYear $3 ; then 
      echo "$0: $3 n'est pas bissextile; fvrier n'a donc pas 29 jours" >&2 
      exit 1
    fi
  else
    echo "$0: mauvaise valeur de jour: $month n'a pas $1 jours" >&2
    exit 1 
  fi
fi

echo "Date valide: $newdate"

exit 0
