1

I have this piece of code in the middle of my web application.

  if (preg_match ("/^[-0-9]/", $strDate) == TRUE)
  {
      $dateParts = explode("-", $strDate);
      if (count($dateParts) === 3)
      {
          try
          {
              if (checkdate($dateParts[0], $dateParts[1], $dateParts[2]) === TRUE)
              {
                  return TRUE;
              }
          }
          catch (Exception $e)
          {
              //purposely blank for now.
          }
      }
  }

I haven't included any surrounding code because it's a fairly lengthy app. To start, the $strDate variable I know exactly what is held in there. I can echo it out right before the if statement begins. If $strDate is a valid date or any combination of 'TBD' the statement validates as expected. The problem comes when an invalid date enters the function.

For instance,

$strDate = '03-01-2017asdf';

With this input I would expect the preg_match to catch it and kick it out of the if statement. Instead it runs the try-except and php throws a non formed number error. Any ideas what I am doing wrong here? I'm sure it has to do with my preg_match statement.

JazZ
  • 4,469
  • 2
  • 20
  • 40
Rashid 'Lee' Ibrahim
  • 1,357
  • 1
  • 9
  • 21

4 Answers4

3

Change your regular expression to require a match until the end of the input string:

/^[-0-9]+$/

So add the + to say you can have multiple digits and hyphens, and then the $ to say that the previous pattern must match until the end of the string, so nothing else can be added like in your example. Of course, you could look for more complex regular expressions that check for valid parts of the date, the number of hyphens, ... etc, which can become quite complex, as you can see in this answer.

Community
  • 1
  • 1
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    Glad that you added `$` sign, but the date pattern still could be better. – MaxZoom Mar 01 '17 at 22:37
  • Yea, folding the date match into the pattern was the next step. I just wanted to get this part working first. This totally worked! Thanks! I knew it was a little tiny error like that and just couldn't figure it out. After searching on here and around the web for hours I gave up and actually asked a question. – Rashid 'Lee' Ibrahim Mar 01 '17 at 22:44
  • It would be easier to ready if you use paragraphs ;-) But UP from me anyway – MaxZoom Mar 01 '17 at 22:53
  • While I agree text has to be broken down into paragraphs, I don't think every sentence has to be a separate paragraph either :P – trincot Mar 01 '17 at 22:57
0

Your preg_match checks whether the $strDate begins with a digit - not whether the date format altogether is correct... Since 03-01-2017asdf begins with a digit, the condition results as TRUE.

For the given date format (MM-DD-YYYY), you may use this code:

if (preg_match ("/^(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])-[0-9]{4}$/", $strDate) == TRUE)
Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
0

I suggest you to validate and format your dates to use Carbon

here an example of code to do what you do in your function:

use Carbon\Carbon;
class DateHelper
{
    /**
     * @param $strDate valid format d-m-Y
     */
    public static function validate($strDate)
    {
        try {
            $carbon = Carbon::createFromFormat('d-m-Y', $strDate);
            return true;
        } catch (\Exception) {
            //invalid date
        }

        return false;
    }

}

var_dump(DateHelper::validate('03-01-2017asdf'));  //return false
var_dump(DateHelper::validate('03-01-2017'));  //return true
Vitaliy Ryaboy
  • 471
  • 2
  • 10
0

The most elegant and shortest way to validate your dates would be to use the DateTime php object.

You could build your function like this :

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

function was copied from this answer or php.net

i.e. :

var_dump(validateDate('03-01-2017asdf', 'm-d-Y')); // bool(false)
var_dump(validateDate('03-01-2017', 'm-d-Y')); // bool(true)

So your validation condition will look like this :

if (validateDate($strDate, 'm-d-Y')) {
    ...
    // Do some stuff
    ...
}

Hope it helps.

Glavić
  • 42,781
  • 13
  • 77
  • 107
JazZ
  • 4,469
  • 2
  • 20
  • 40