我从一个API接收到一个日期字符串,它的格式是yyyy-mm-dd。

我目前正在使用一个正则表达式来验证字符串格式,这是可以工作的,但我可以看到一些情况下,根据字符串,它可能是一个正确的格式,但实际上是一个无效的日期。例如,2013年13月1日。

在PHP中是否有更好的方法来获取一个字符串,如2013-13-01,并判断它是否是yyyy-mm-dd格式的有效日期?


当前回答

要添加到已接受的答案上,可以通过检查格式化的日期是否是DateTime的实例来进一步检查有效日期或DateTime。

$date = DateTime::createFromFormat('Ymd', $value);
$is_datetime = ($date instanceof DateTime);
$is_valid_datetime_format = $is_datetime
  ? ($date->format('Ymd') === $value)
  : false;

if (!$is_datetime || !$is_valid_datetime_format) {
  // Not a valid date.
  return false;
}

这将捕获任何不是DateTime的值,如随机字符串或无效日期,如20202020。

其他回答

你也可以解析月份日期和年份的日期,然后你可以使用PHP函数checkdate(),你可以在这里读到:http://php.net/manual/en/function.checkdate.php

你也可以试试这个:

$date="2013-13-01";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date))
    {
        echo 'Date is valid';
    }else{
        echo 'Date is invalid';
    }

你可以使用DateTime::createFromFormat()来实现这个目的:

function validateDate($date, $format = 'Y-m-d')
{
    $d = DateTime::createFromFormat($format, $date);
    // The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
    return $d && $d->format($format) === $date;
}

[从这个答案中得到的函数。在php.net上也有。原作者:格拉维克。


测试用例:

var_dump(validateDate('2013-13-01'));  // false
var_dump(validateDate('20132-13-01')); // false
var_dump(validateDate('2013-11-32'));  // false
var_dump(validateDate('2012-2-25'));   // false
var_dump(validateDate('2013-12-01'));  // true
var_dump(validateDate('1970-12-01'));  // true
var_dump(validateDate('2012-02-29'));  // true
var_dump(validateDate('2012', 'Y'));   // true
var_dump(validateDate('12012', 'Y'));  // false

演示!

试着让我知道这对我有用

$date = \DateTime::createFromFormat('d/m/Y', $dataRowValue);
if (!empty($date)) {
//Your logic
}else{
//Error
}

如果您传递任何alpha或字母数字值,它将返回给您空值

测试过的Regex解决方案:

    function isValidDate($date)
    {
            if (preg_match("/^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$/", $date)) {
                    return $date;
            }
            return null;
    }

如果日期无效或不是yyyy-mm-dd格式,将返回null,否则将返回日期。

恐怕大多数投票的解决方案(https://stackoverflow.com/a/19271434/3283279)不能正常工作。第四个测试用例(var_dump(validateDate('2012-2-25'));// false)是错误的。日期是正确的,因为它对应的格式- m允许一个月前导零或不前导零(参见:http://php.net/manual/en/datetime.createfromformat.php)。因此,日期2012-2-25的格式是Y-m-d,测试用例必须为真而不是假。

我认为更好的解决方案是测试可能的错误,如下所示:

function validateDate($date, $format = 'Y-m-d') {
    DateTime::createFromFormat($format, $date);
    $errors = DateTime::getLastErrors();

    return $errors['warning_count'] === 0 && $errors['error_count'] === 0;
}