Regex to validate date in PHP using format as YYYY-MM-DD

前端 未结 3 1886
梦谈多话
梦谈多话 2021-01-05 07:59

I am trying to make a date regex validator. The issue I\'m having is that I\'m using an input field with \"date\" type, which works like a charm in Chrome; it o

3条回答
  •  抹茶落季
    2021-01-05 08:40

    Check and validate YYYY-MM-DD date in one line statement

    function isValidDate($date) {
        return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
            ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
            : false;
    }
    

    See the details in my answer here.

    Don't use blindly DateTime::createFromFormat to validate dates. Let's take non-existent date 2018-02-30 and see:

    $d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
    var_dump((bool) $d); // bool(true)
    

    Yes, it returns true, not false as you may expected. More interesting:

    $d = DateTime::createFromFormat("Y-m-d", "2018-99-99");
    var_dump((bool) $d); // bool(true)
    

    Also true... So, it validates just the number of digits. One more try:

    $d = DateTime::createFromFormat("Y-m-d", "ABCD-99-99");
    var_dump($d); // bool(false)
    

    At last false.

    What is going on here we can see from this snippet:

    $d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
    var_dump($d);
    
    // var_dump OUTPUT
    object(DateTime)#1 (3) {
      ["date"]=>
      string(26) "2018-03-02 16:41:34.000000"
      ["timezone_type"]=>
      int(3)
      ["timezone"]=>
      string(3) "UTC"
    }
    

    As you can see when we pass non-existent 2018-02-30, the DateTime object contains 2018-03-02. I assume that it's because February 2018 has 28 days, i.e. the maximum date is 2018-02-28, and when we pass the day 30, createFromFormat just adds 30 days to the 2018-02-01 and create new date without any preceding date validation.

提交回复
热议问题