#!/bin/bash
#< Thorough date validation script - checks leap years too
PROGNAME=`basename $0`
MODE="UK"
function usage() {
echo "Usage: ${PROGNAME} [-u] [dd|mm] [dd|mm] [yyyy]" >&2
}
case ${1} in
'-u') MODE="US"
shift
;;
esac
if [ "${#}" -ne "3" ]; then
usage
fi
case ${MODE} in
"UK") DAY="${1}"
MONTH="${2}"
YEAR="${3}"
;;
"US") MONTH="${1}"
DAY="${2}"
YEAR="${3}"
;;
esac
DATE="${1} ${2} ${3}"
echo "${DAY}" | grep "^[0-9][0-9]$" >/dev/null 2>&1
if [ "${?}" -ne "0" ]; then
echo "Error: ${DAY} not in DD format" >&2
exit 1
fi
echo "${MONTH}" | grep "^[0-9][0-9]$" >/dev/null 2>&1
if [ "${?}" -ne "0" ]; then
echo "Error: ${MONTH} is not in MM format" >&2
exit 1
fi
if [ "${MONTH}" -gt "12" -o "${MONTH}" -lt "1" ]; then
echo "Error: ${MONTH} is not a valid month!" >&2
exit 1
fi
echo "${YEAR}" | grep "^[0-9][0-9][0-9][0-9]$" >/dev/null 2>&1
if [ "${?}" -ne "0" ]; then
echo "Error: ${YEAR} is not in YYYY format" >&2
exit 1
fi
if [ "${YEAR}" -lt "1950" -o "${YEAR}" -gt "2050" ]; then
echo "Error: ${YEAR} not between 1950 and 2050 inclusive" >&2
exit 1
fi
case ${MONTH} in
01|03|05|07|08|09|10|12)
if [ "${DAY}" -gt "31" -o "${DAY}" -lt "1" ]; then
echo "Error: ${DAY} not a valid day" >&2
exit 1
fi
;;
04|06|09|11)
if [ "${DAY}" -gt "30" -o "${DAY}" -lt "1" ]; then
echo "Error: ${DAY} not a valid day" >&2
exit 1
fi
;;
02) # Damn February ;-)
if [ "$((YEAR % 4))" -ne "0" ]; then
LEAP=1
elif [ "$((YEAR % 400))" -eq "0" ]; then
LEAP=0
elif [ "$((YEAR % 100))" -eq "0" ]; then
LEAP=1
else
LEAP=0
fi
if [ "${LEAP}" -eq "0" ]; then
if [ "${DAY}" -gt "29" -o "${DAY}" -lt "1" ]; then
echo "Error: ${DAY} not a valid day" >&2
exit 1
fi
else
if [ "${DAY}" -gt "28" -o "${DAY}" -lt "1" ]; then
echo "Error: ${DAY} not a valid day" >&2
exit 1
fi
fi
;;
esac
echo "${DATE} is a valid date!"
exit 0