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

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

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


当前回答

试一试:

$date = "2017-10-01";


function date_checker($input,$devider){
  $output = false;

  $input = explode($devider, $input);
  $year = $input[0];
  $month = $input[1];
  $day = $input[2];

  if (is_numeric($year) && is_numeric($month) && is_numeric($day)) {
    if (strlen($year) == 4 && strlen($month) == 2 && strlen($day) == 2) {
      $output = true;
    }
  }
  return $output;
}

if (date_checker($date, '-')) {
  echo "The function is working";
}else {
  echo "The function isNOT working";
}

其他回答

    /**** date check is a recursive function. it's need 3 argument 
    MONTH,DAY,YEAR. ******/

    $always_valid_date = $this->date_check($month,$day,$year);

    private function date_check($month,$day,$year){

        /** checkdate() is a php function that check a date is valid 
        or not. if valid date it's return true else false.   **/

        $status = checkdate($month,$day,$year);

        if($status == true){

            $always_valid_date = $year . '-' . $month . '-' . $day;

            return $always_valid_date;

        }else{
            $day = ($day - 1);

            /**recursive call**/

            return $this->date_check($month,$day,$year);
        }

    }

恐怕大多数投票的解决方案(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;
}

我有这样的东西,即使使用PHP,我也喜欢寻找函数式解决方案。例如,@migli给出的答案非常好,非常灵活和优雅。

但它有一个问题:如果需要用相同的格式验证大量DateTime字符串怎么办?你将不得不到处重复这种格式,这违背了DRY原则。我们可以把格式放在一个常量中,但是,我们仍然必须把这个常量作为参数传递给每个函数调用。

但是不要再害怕了!我们可以用咖喱来拯救我们!PHP并没有让这个任务变得愉快,但仍然可以用PHP实现curry:

<?php
function validateDateTime($format)
{
    return function($dateStr) use ($format) {
        $date = DateTime::createFromFormat($format, $dateStr);
        return $date && $date->format($format) === $dateStr;
    };
}

那么,我们刚刚做了什么?基本上,我们将函数体包装在一个匿名函数中,并返回这样的函数。我们可以像这样调用验证函数:

validateDateTime('Y-m-d H:i:s')('2017-02-06 17:07:11'); // true

是啊,差别不大…但真正的力量来自于部分应用的函数,这是通过咖喱实现的:

// Get a partially applied function
$validate = validateDateTime('Y-m-d H:i:s');

// Now you can use it everywhere, without repeating the format!
$validate('2017-02-06 17:09:31'); // true
$validate('1999-03-31 07:07:07'); // true
$validate('13-2-4 3:2:45'); // false

函数式编程!

判断是否有字符串是日期

function checkIsAValidDate($myDateString){
    return (bool)strtotime($myDateString);
}

你也可以解析月份日期和年份的日期,然后你可以使用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';
    }