Hi,

I'm needing to validate user input that they entered the date in the correct format:
(YYYY-MM-DD) or (YYYY/MM/DD)
and to accept something like this:

YYYY-M-D

or any pattern like that:
YYYY-MM-D
YYYY-M-DD

and to make sure the months and days are within an appropriate calendar range.

I'm thinking ereg function is the way to go, but I'm not understanding the tricks of it to allow for this flexibility. So far I had a pattern like:

$value = "200[0-9]-[0-1][0-9]-[0-3][0-9]"

But that only handles a YYYY-MM-DD format. I'm not familiar with how to make this a bit more flexible.

Any help would be appreciated.

    e.g. your var has following string:

    $date = '2001/01/12';

    now:
    if (eregi('[0-9]\/[0-9]\/[0-9]', $date) {
       // split the string with / character, so you will have it in 3 peices
       $validate = explode('/', $date);

       if ($validate[0] != '2001') {
          // the year is not 2001!
       }

       if ($validate[1] > '12') {
          // sorry, you can have more than 12 months!
       }
    }
    else {
       // sorry wrong date format
    }

    i hope you get the idea, of what i am doing above.

    Daarius...

      okay, so I see that you are exploding the string using the '/' however I don't understand the purpose of the

      eregi('[0-9]\/[0-9]\/[0-9]', $date)

      expression above.

      and what does \ and / do?

      Thanks for your help.

        the first ereg() e.g:
        eregi('[0-9]\/[0-9]\/[0-9]', $string);

        will make sure it is dealing with the date pattern 9999/99/99

        else if not, then simply say the pattern in completely wrong, so there is no need of working on this string any more.

        the backslah \ tells the PHP that the forward slash / is actually part of the string, and not the delimiter. so you use \/ in this case. and if you had the backslash in yur string, then you have to use \.

        Daarius...

          Thank you for your clarity.
          One more thing...What if the delimeter can be either / or - Could I still use ereg for this, or would there be a more appropriate function, say perhaps strstr?

            Okay, here's my function. There's probably a much cleaner way to write it, but at least it works:

            function validateDate($date){

            if ( strstr($date, "/" ) )
            $ch = "/";
            elseif ( strstr($date, "-" ) )
            $ch = "-";
            else
            return false;

            $parts = explode($ch, $date );

            if ($parts[0] < 2000 || $parts[0] > 2010 )
            return false;
            if ($parts[1] > 12)
            return false;
            if ($parts[2] > 32)
            return false;
            else
            return true;

            }//end validateDate

              What if the delimeter can be either / or -

              Then you say:

              &nbsp;&nbsp;if (eregi('[0-9][-\/][0-9][-\/][0-9]', ...

              In just the same way as you're using [] to match a range of characters between 0-9, you can also match a group of characters for the delimiter.

              But you can do even better than this:

              function validate_date( $date )
              {
              if (ereg('([0-9]{4})-\/-\/', $date, $val))
              &nbsp;&nbsp;{
              &nbsp;&nbsp;if ($val[1] >= $min_year && $val[1] <= $max_year)
              &nbsp;&nbsp;&nbsp;&nbsp;{
              &nbsp;&nbsp;&nbsp;&nbsp;return // bad year
              &nbsp;&nbsp;&nbsp;&nbsp;}
              &nbsp;&nbsp;else
              &nbsp;&nbsp;&nbsp;&nbsp;{
              &nbsp;&nbsp;&nbsp;&nbsp;return checkdate ($val[2], val[1], $val[3] );
              &nbsp;&nbsp;&nbsp;&nbsp;}
              &nbsp;&nbsp;}
              else
              &nbsp;&nbsp;{
              return false;
              }

              (1) Putting parens around the various parts of the regex causes them to be copied into the array $var, saving a separate call to split() or explode().

              (2) Using {n,n} for each component specifies the length that must match. You might want to vary the number of digits required for the year, if you expect to be entering dates before 1000 AD.

              (3) The built-in function checkdate() does the rest of the heavy lifting.

                Sure is difficult posting readably-indented source code! Sorry for the typos:

                &nbsp;&nbsp;&nbsp;return // bad year

                should of course say

                &nbsp;&nbsp;&nbsp;return false; // bad year

                Also, there's a missing closing brace at the end of the last else-block.

                  a year later

                  Great little function! Thanks!

                  Here's two more things I needed to do to get it working:

                  The line:

                    return checkdate($val[2], val[1], $val[3] );

                  should have a dollar sign in front of val[1]:

                    return checkdate($val[2], $val[1], $val[3] );

                  And I think you meant to put this line right after the if, statement so that it returns if the year is between min_year and max_year, like so:

                  if ( ereg( '([0-9]{4}) [-\/] ([0-9]{1,2}) [-\/] ([0-9]{1,2})', $date, $val ) )
                  {
                  if ($val[1] >= $min_year && $val[1] <= $max_year)
                  {
                  return checkdate($val[2], $val[1], $val[3] );
                  }
                  else
                  {
                  return false; // bad year
                  }
                  }

                    Write a Reply...