views:

628

answers:

4

I'm trying to do validation of a date entered as numbers only. (e.g. 09042009 as 09/04/2009) The code now just checks the length of the date.

How would I validate not only length of the date entry but also that it is a real date? What would be the syntax for combining tests and regular expression?

Code as it exists now:

echo "Please enter the date you want (e.g. 07142009)"
level=1;
while [ $level -gt 0 ]; do
        read date;
        dateleng=`expr length $date`
        if [ dateleng -ne 8 ]; then
                echo "Bad date, please re-enter"; 
                else level=0;
        fi
done

This is in KSH on an old Unix system.

+1  A: 

Does this script help?

Jeremy Stein
Yes! That helped me to see the syntax for the KSH logical operators AND = -a and OR = -o (at least in SH, not sure if these carry over to my KSH)
jjclarkson
A: 

Call date -d $date

See if it returns an error.

Jeremy Stein
My "date" doesn't like that:>date -d 09042009date: -d illegal optionUsage: date [-u] [+format] date [-u] [-t [[CC]YYMMDDhhmm[.SS] | MMDDhhmm[YY] ]
jjclarkson
Oh, I didn't realize that option wasn't universal. Sorry about that. It would have been an easy fix!
Jeremy Stein
+1  A: 

All right, if you really want to do it as a singe regex and you don't care about leap years, try this:

^(((0[469])|(1[1]))((0[1-9])|([12][0-9])|(30))|((0[13578])|(1[02]))((0[1-9])|([12][0-9])|(3[01]))|(02)((0[1-9])|(1[0-9])|(2[0-8])))[0-9]{4}$
Beta
+1  A: 

Write a small C program that accepts the date as an argument and fills in a struct tm structure. Then format the date using the standard C library routines and compare it to the input date string.

#include <time.h>
main(int argc, char *argv[])
{
 struct tm tmx, *tm2;
    char tmbuf[9];
    time_t timet;
    if (argc < 1)
       exit(2);
    tmx.tm_sec = tmx.tm_min = tmx.tm_hour = tmx.tm_mday = tmx.tm_mon = 
    tmx.tm_year = tmx.tm_wday = tmx.tm_yday = tmx.tm_isdst = 0;
    tmx.tm_mon = (argv[1][0] - '0') * 10 + argv[1][1] - '0' - 1;
    tmx.tm_mday = (argv[1][2] - '0') * 10 + argv[1][3] - '0';
    tmx.tm_year = atoi(&argv[1][4]) - 1900;
    if ((timet = mktime(&tmx)) != (time_t)-1) {
        tm2 = localtime(&timet);
        strftime(tmbuf, sizeof(tmbuf), "%m%d%Y", tm2);
        if (strcmp(argv[1], tmbuf) == 0)
            exit(0);
    }
    exit(1);
}
/*
cc valdate.c -o valdate
*/


If the C library date formatted string doesn't equal the input string, the date is invalid and the C program will exit with a status of 1. Otherwise the date is valid, and the exit status is 0. The shell script then uses the C program to validate the date.

echo "Please enter the date you want (e.g. MMDDYYYY)"
read date
if valdate "$date"; then
    echo "Bad date ($date), please re-enter"
fi
Howard Hong