# Script for validating a date e.g. 11291985

• 01-04-2013
Garrett85
Script for validating a date e.g. 11291985
This script whould be able to determine if a date that has been entered in as 8 digits is valid or not.

It will first check that there are 8 digits, if so everything is good.

It will then theck that the month value is > 0 & < 13, if so everything is good.

In order to get the day I need to fist find out if it's leap year or not to determin if the maximum number of da

ys is 28 or 29

I use a function "is_leap_year" to determine if it is or is not leap year.

I use a function "get_day" to check that the day is > 0 & <= CALENDER[MM]

For some reason my program is running the "get_day" function even when the function "is_leap_year" returns true, in that case it would only call "get_day" in the else clause of that code block. Please help I am stumped.

Code:

```#! /bin/bash -x ############################# ### FUNCTION-is_leap_year ### ############################# is_leap_year() {         PART1=`expr \${YY} % 4`         PART2=`expr \${YY} % 100`         if [[ 0 -eq \${PART1} ]] && [[ 0 -ne \${PART2} ]] || [[ 0 -eq `expr \${YY} % 400` ]]; then                 result=true         else                 result=false         fi } #################### ### END FUNCTION ### #################### ######################## ### FUNCTION-get_day ### ######################## get_day() {         if [[ \${DD} -gt 0 ]] && [[ \${DD} -le \${CALENDER[\${MM}]} ]]; then #{                 DAY="GOOD"         else                 DAY="BAD"         fi #} } #################### ### END FUNCTION ### #################### # This is the calender array for the DateValidation program CALENDER=(31 28 31 30 31 30 31 31 30 31 30 31) read -p "Enter a date for validation: " DATE # establish the varible LEN to hold the number of characters in Date, 8 is the only valid number LEN=\$(echo \${#DATE}) if [ \$LEN -eq 8 ]; then #{           # set date dariables MM, DD, & YY         MM=\${DATE:0:2}         DD=\${DATE:2:2}         YY=\${DATE:4:4}         if [ \${YY} -gt 0 ]; then #{                 if [ \${MM} -gt 0 ] && [ \${MM} -lt 13 ]; then                         if [ "\${MM} -ne 02" ]; then                                 get_day \${DD}                                 if [ \${DAY} == GOOD ]; then                                         echo "\${DATE} is a valid date!"                                 else                                         echo "\${DD} is invalid!"                                 fi #}                         else                                 is_leap_year \${YY}                                 if [ "\${result} == true" ]; then                                         if [ \${DD} -gt 0 ] && [ \${DD} -le 29 ]; then                                                 echo "\${DATE} is a valid date"                                         else                                                 echo "The day you entered for this date is invalid"                                         fi #}                                 else                                         get_day \${DD}                                         if [ \${DAY} == GOOD ]; then                                                 echo "\${Date} is a valid date"                                         else                                                 echo "Date \${DD} is invalid"                                         fi #}                                 fi #}                         fi #}                 else                         echo "\${MM} is invalid!"                 fi #}         else                 echo "\${YY} is invalid!"         fi #} else         echo "Incalid number of digits for a valid date" fi #}```
• 01-04-2013
atreyu
Code:

`if [ "\${result} == true" ]; then`
try evaluating like this:
Code:

`if [ "\$result" == 'true' ]; then`
but what I generally do is return a 0 or 1 from a function, instead of messing with variables, e.g.:

Code:

```#!/bin/bash function testfunc() {   local var=\$1   if [ "\$var" == 'foo' ]; then     return 0   else     return 1   fi } # now call the function testfunc foo && echo Successful || echo Failed # you could also evaluate the return value, e.g.: testfunc foo if [ \$? -eq 0 ]; then   echo The function returned success else   echo The function returned with error fi```
• 01-04-2013
Garrett85
I thought there was no returning in bash?
• 01-04-2013
Garrett85
When I enter the date 02292001 I get "02292001 is a valid date' I don't understand. 29 should be invalid since there are only 28 days in FEB unless it's leap year and 2001 is not leap year. What am I doing wrong here?
• 01-05-2013
atreyu
Quote:

Originally Posted by Garrett85
I thought there was no returning in bash?

You can return from a bash function, absolutely, but you must return an integer, not a string. It is then easy to evaluate that integer as a return value.
• 01-05-2013
atreyu
Quote:

Originally Posted by Garrett85
When I enter the date 02292001 I get "02292001 is a valid date' I don't understand. 29 should be invalid since there are only 28 days in FEB unless it's leap year and 2001 is not leap year. What am I doing wrong here?

It is your use of arrays that is tripping you up. Arrays start at 0, not 1. So subtract 1 from your \$MM before getting the max # of days for that month. E.g.:

Code:

```# FUNCTION-get_day get_day(){   local mo=\$(( \$MM - 1 ))   if [[ \$DD -gt 0 ]] && [[ \$DD -le \${CALENDER[\${mo}]} ]]; then     DAY="GOOD"   else     DAY="BAD"   fi }```
Running this bit of code in your script will elucidate what your array holds:
Code:

```CALENDER=(31 28 31 30 31 30 31 31 30 31 30 31) for ((i=0;i<\${#CALENDER[*]};i++)) {   echo month \$i days: \${CALENDER[\$i]} }```
• 01-05-2013
Garrett85
If I run the line if [[ \${DD} -gt 0 ]] && [[ \${DD} -le \${CALENDER[\${SECONDDIGIT}]} ]]; DD is run against 31, I belive that 31 is from the [0] index because if I then change the line to { to if [[ \${DD} -gt 0 ]] && [[ \${DD} -le \${CALENDER[\${SECONDDIGIT+1}]} ]]; then #{ DD is then run against 28 every time. It looks to me like my SECONDDIGIT & MM indexes are not being used. It looks like I'M always fetching the first index no matter wha,t and the second index if I add a + 1. Any ideas?
• 01-05-2013
atreyu
Quote:

Originally Posted by Garrett85
It looks to me like my SECONDDIGIT & MM indexes are not being used. It looks like I'M always fetching the first index no matter wha,t and the second index if I add a + 1. Any ideas?

Where are you getting SECONDDIGIT from? Can you show the whole code?
• 01-05-2013
Garrett85
Sorry, I didn't realize I had posted older code. The whole thing is below.

Code:

```#! /bin/bash -x # This is the calender array for the DateValidation program CALENDER=(31 28 31 30 31 30 31 31 30 31 30 31) ############################# ### FUNCTION-is_leap_year ### ############################# is_leap_year() {         PART1=`expr \${YY} % 4`         PART2=`expr \${YY} % 100`         if [[ 0 -eq \${PART1} ]] && [[ 0 -ne \${PART2} ]] || [[ 0 -eq `expr \${YY} % 400` ]]; then #{                 result=true         else                 result=false         fi #} } #################### ### END FUNCTION ### #################### ######################## ### FUNCTION-get_day ### ######################## get_day() {         DAY="BAD"         FIRSTDIGIT=\${MM:0:1}         SECONDDIGIT=\${MM:1:1}         if [[ \${FIRSTDIGIT} -eq 0 ]]; then #{                 if [[ \${DD} -gt 0 ]] && [[ \${DD} -le \${CALENDER[\${SECONDDIGIT+1}]} ]]; then #{                         DAY="GOOD"                 fi #}         else                 if [[ \${DD} -gt 0 ]] && [[ \${DD} -le \${CALENDER[\${MM}]} ]]; then #{                         DAY="GOOD"                 fi #}         fi #} } #################### ### END FUNCTION ### #################### KEEPGOING=1 while [[ \${KEEPGOING} -eq 1 ]]; do read -p "Enter a date for validation: " DATE # establish the varible LEN to hold the number of characters in Date, 8 is the only valid number LEN=\$(echo \${#DATE}) if [[ "\${DATE}" == exit ]]; then         \$KEEPGOING=0 elif [ \$LEN -eq 8 ]; then #{           # set date dariables MM, DD, & YY         MM=\${DATE:0:2}         DD=\${DATE:2:2}         YY=\${DATE:4:4}         if [ \${YY} -gt 0 ]; then #{                 if [ \${MM} -gt 0 ] && [ \${MM} -lt 13 ]; then                         if [ \${MM} -eq 02 ]; then                                                                 is_leap_year \${YY}                                 if [ \$result == true ]; then                                         if [ \${DD} -gt 0 ] && [ \${DD} -le 29 ]; then                                                 echo "\${DATE} is a valid date!"                                         else                                                 echo "\${DD} is invalid for this date!"                                         fi #}                                 else                                         get_day \${DD}                                         if [ \${DAY} == GOOD ]; then                                                 echo "\${Date} is a valid date!"                                         else                                                 echo "\${DD} is invalid for this date!"                                         fi #}                                 fi #}                         else                                 get_day \${DD}                                 if [ \${DAY} == GOOD ]; then                                         echo "\${DATE} is a valid date!"                                 else                                         echo "\${DD} is invalid for this date!"                                 fi #}                         fi #}                 else                         echo "\${MM} is invalid for this date!"                 fi #}         else                 echo "\${YY} is invalid for this date!"         fi #} else         echo "Invalid number of digits for a date!" fi #} done```