217

我从 API 接收日期字符串,它的格式为yyyy-mm-dd.

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

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

4

18 回答 18

533

您可以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上。最初由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

演示!

于 2013-10-09T11:59:54.410 回答
93

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

function checkIsAValidDate($myDateString){
    return (bool)strtotime($myDateString);
}
于 2014-06-25T06:15:01.033 回答
44

使用 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
于 2015-03-17T07:39:55.417 回答
17

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

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

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

// These return true
validateDateTime('2001-03-10 17:16:18', 'Y-m-d H:i:s');
validateDateTime('2001-03-10', 'Y-m-d');
validateDateTime('2001', 'Y');
validateDateTime('Mon', 'D');
validateDateTime('March 10, 2001, 5:16 pm', 'F j, Y, g:i a');
validateDateTime('March 10, 2001, 5:16 pm', 'F j, Y, g:i a');
validateDateTime('03.10.01', 'm.d.y');
validateDateTime('10, 3, 2001', 'j, n, Y');
validateDateTime('20010310', 'Ymd');
validateDateTime('05-16-18, 10-03-01', 'h-i-s, j-m-y');
validateDateTime('Monday 8th of August 2005 03:12:46 PM', 'l jS \of F Y h:i:s A');
validateDateTime('Wed, 25 Sep 2013 15:28:57', 'D, d M Y H:i:s');
validateDateTime('17:03:18 is the time', 'H:m:s \i\s \t\h\e \t\i\m\e');
validateDateTime('17:16:18', 'H:i:s');

// These return false
validateDateTime('2001-03-10 17:16:18', 'Y-m-D H:i:s');
validateDateTime('2001', 'm');
validateDateTime('Mon', 'D-m-y');
validateDateTime('Mon', 'D-m-y');
validateDateTime('2001-13-04', 'Y-m-d');
于 2016-10-17T10:24:15.360 回答
15

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

$timestamp = strtotime($date);
return $timestamp ? $date : null;
于 2015-06-30T08:32:04.490 回答
11

您还可以解析月份日期和年份的日期,然后您可以使用checkdate()您可以在此处阅读的 PHP 函数: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';
    }
于 2013-10-09T12:02:03.063 回答
11

检查给定日期是否有效的最简单方法可能是将其转换为 unixtime 使用strtotime,将其格式化为给定日期的格式,然后进行比较:

function isValidDate($date) { return date('Y-m-d', strtotime($date)) === $date; }

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

于 2017-07-03T19:16:12.887 回答
9

恐怕大多数投票的解决方案(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的格式为 Ymd,并且测试用例必须为真而不是假。

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

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

    return $errors['warning_count'] === 0 && $errors['error_count'] === 0;
}
于 2019-02-28T07:35:01.270 回答
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
于 2016-02-29T19:25:13.997 回答
7

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

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

但不要再害怕了!我们可以使用柯里化来拯救我们!PHP 不会使这项任务变得愉快,但仍然可以使用 PHP 实现柯里化:

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

于 2017-02-06T16:17:28.493 回答
4

这个怎么样?

我们只是使用一个 try-catch 块。

$dateTime = 'an invalid datetime';

try {
    $dateTimeObject = new DateTime($dateTime);
} catch (Exception $exc) {
    echo 'Do something with an invalid DateTime';
}

这种方法不仅限于一种日期/时间格式,而且您不需要定义任何函数。

于 2017-09-07T10:53:53.517 回答
4

使用checkdate函数进行验证:

$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
}
于 2019-06-11T11:47:14.853 回答
1

经过测试的正则表达式解决方案:

    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,否则将返回日期。

于 2017-03-14T20:17:04.117 回答
1
/*********************************************************************************
Returns TRUE if the input parameter is a valid date string in "YYYY-MM-DD" format (aka "MySQL date format")
The date separator can be only the '-' character.
*********************************************************************************/
function isMysqlDate($yyyymmdd)
{
    return checkdate(substr($yyyymmdd, 5, 2), substr($yyyymmdd, 8), substr($yyyymmdd, 0, 4)) 
        && (substr($yyyymmdd, 4, 1) === '-') 
        && (substr($yyyymmdd, 7, 1) === '-');
}
于 2018-12-09T20:41:01.030 回答
1

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

于 2021-04-22T15:41:27.977 回答
0
    /**** 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);
        }

    }
于 2017-09-01T10:43:51.643 回答
0

试着让我知道它对我有用

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

如果您传递任何 alpha 或 alphanumberic 值,它将为您提供空值作为回报

于 2021-09-22T13:12:06.107 回答
-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";
}
于 2017-11-10T16:50:50.083 回答