正确确定日期字符串是否为该格式的有效日期

时间:2013-10-09 11:58:04

标签: php date datetime

我从API收到日期字符串,格式为yyyy-mm-dd

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

有没有更好的方法在PHP中使用2013-13-01之类的字符串,并告诉格式yyyy-mm-dd它是否是有效日期?

17 个答案:

答案 0 :(得分:380)

您可以使用DateTime类来实现此目的:

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;
}

[取自this answer的函数。同样在php.net。最初由Glavić撰写。]


测试用例:

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

Demo!

答案 1 :(得分:68)

确定任何字符串是否为日期

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

答案 2 :(得分:29)

使用php预建函数以简单的方式使用:

function checkmydate($date) {
  $tempDate = explode('-', $date);
  // checkdate(month, day, year)
  return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}

<强>测试

   checkmydate('2015-12-01'); //true
   checkmydate('2015-14-04'); //false

答案 3 :(得分:14)

确定字符串是否为日期,即使字符串是非标准格式

(strtotime不接受任何自定义格式)

var_dump

答案 4 :(得分:12)

这个选项不仅简单,而且几乎可以接受任何格式,但是对于非标准格式,它可能是错误的。

$timestamp = strtotime($date);
return $timestamp ? $date : null;

答案 5 :(得分:9)

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

答案 6 :(得分:7)

根据cl-sah的回答,但这听起来更好,更短......

function checkmydate($date) {
  $tempDate = explode('-', $date);
  return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}

测试

checkmydate('2015-12-01');//true
checkmydate('2015-14-04');//false

答案 7 :(得分:6)

我有这个东西,即使使用PHP,我也想找到功能性解决方案。因此,例如,@ migli给出的答案确实很好,非常灵活和优雅。

但它有一个问题:如果你需要用相同的格式验证很多DateTime字符串怎么办?你必须在整个地方重复这种格式,这与 DRY 原则背道而驰。我们可以将格式放在常量中,但是,我们必须将常量作为参数传递给每个函数调用。

但不要再害怕了!我们可以使用 currying 来救援! PHP不会使这个任务变得愉快,但仍然可以用PHP实现currying:

<?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

功能编程FTW!

答案 8 :(得分:5)

检查给定日期是否有效的最简单方法可能是使用<script> var i = 0; for (i = 0; i < 10; i++) { console.log("Text"); } </script> 将其转换为unixtime,将其格式化为给定日期的格式,然后进行比较:

<script> console.log("Text"); </script>

当然,您可以使用正则表达式来检查有效性,但它将限制为给定的格式,每次您必须编辑它以满足其他格式,并且它将超过要求。内置函数是实现工作的最佳方式(在大多数情况下)。

答案 9 :(得分:3)

这个怎么样?

我们只使用try-catch块。

ConfigureAwait(false)

此方法不仅限于一种日期/时间格式,您无需定义任何功能。

答案 10 :(得分:1)

经过测试的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,否则返回日期。

答案 11 :(得分:0)

Layer

答案 12 :(得分:0)

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

我相信更好的解决方案是按如下方式测试可能的错误:

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

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

答案 13 :(得分:0)

使用检查日期功能进行验证:

$date = '2019-02-30';

$date_parts = explode( '-', $date );

if(checkdate( $date_parts[1], $date_parts[2], $date_parts[0] )){
    //date is valid
}else{
    //date is invalid
}

答案 14 :(得分:0)

要添加到已接受的答案中,您可以通过检查格式化日期是否为 instanceof 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

答案 15 :(得分:-1)

    /**** 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);
        }

    }

答案 16 :(得分:-1)

尝试一下:

$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";
}