Shell script to determine whether the date entered is correct

Time:2021-6-11

Today’s topic is to determine whether the input date is correct, using the function in our previous 03 example
Here’s the code


#!/bin/sh
# valid-date -- Validates a date, taking into account leap year rules.

exceedsDaysInMonth()
{

 case $(echo $1|tr '[:upper:]' '[:lower:]') in
  jan* ) days=31  ;; feb* ) days=28  ;;
  mar* ) days=31  ;; apr* ) days=30  ;;
  may* ) days=31  ;; jun* ) days=30  ;;
  jul* ) days=31  ;; aug* ) days=31  ;;
  sep* ) days=30  ;; oct* ) days=31  ;;
  nov* ) days=30  ;; dec* ) days=31  ;;
  * ) echo "$0: Unknown month name $1" >&2; exit 1
  esac

  if [ $2 -lt 1 -o $2 -gt $days ] ; then
   return 1
  else
   return 0  # the day number is valid
  fi
}

isLeapYear()
{

 year=$1
 if [ "$((year % 4))" -ne 0 ] ; then
  return 1 # nope, not a leap year
 elif [ "$((year % 400))" -eq 0 ] ; then
  return 0 # yes, it's a leap year
 elif [ "$((year % 100))" -eq 0 ] ; then
  return 1
 else
  return 0
 fi
}
## Begin main script

if [ $# -ne 3 ] ; then
 echo "Usage: $0 month day year" >&2
 echo "Typical input formats are 8 3 2002" >&2
 exit 1
fi

# Normalize date and split back out returned values


if [ $? -eq 1 ] ; then
 exit 1    # error condition already reported by normdate
fi

monthnoToName()
{
 # Sets the variable 'month' to the appropriate value
 case $1 in
  01|1 ) monthd="Jan"  ;; 02|2 ) monthd="Feb"  ;;
  03|3 ) monthd="Mar"  ;; 04|4 ) monthd="Apr"  ;;
  05|5 ) monthd="May"  ;; 06|6 ) monthd="Jun"  ;;
  07|7 ) monthd="Jul"  ;; 08|8 ) monthd="Aug"  ;;
  09|9 ) monthd="Sep"  ;;   10) monthd="Oct"  ;;
    11) monthd="Nov"  ;;   12) monthd="Dec"  ;;
  * ) echo "$0: Unknown numeric month value $1" >&2; exit 1
  esac
  return 0
}

monthnoToName $1

month="$monthd"
 day="$2"
 year="$3"
 
if ! exceedsDaysInMonth $month "$2" ; then
 if [ "$month" = "Feb" -a "$2" -eq "29" ] ; then
  if ! isLeapYear $3 ; then
   echo "$0: $3 is not a leap year, so Feb doesn't have 29 days" >&2
   exit 1
  fi
 else
  echo "$0: bad day value: $month doesn't have $2 days" >&2
  exit 1
 fi
fi

echo "Valid date: $newdate"

exit 0

analysis:
1) First, judge whether the number of parameters entered by the user is correct, and then use the case $1 in statement to judge whether the month is reasonable.
2) The monthnotoname function appeared in our previous 03 script case, which is used to convert the input number date to a string.
3) Exceedsdaysinmonth is used to determine whether the number of days exceeds the maximum number of days in the corresponding month, followed by if [“$month” = $Feb “- a” $2 “- EQ” 29]; then if ! isLeapYear $3 ; Then it is used to judge the special situation of February in leap year
4) The overall feeling is that the script is still very compact, especially the code used to judge the relationship between leap year and February, which is a bit interesting.