PHP DateTime接受无效日期

Cle*_*man 11 php datetime date

我在使用PHP DateTime类时遇到了麻烦,更具体地说是使用PHP 类DateTime::createFromFormat().

我从字符串中获取日期,然后尝试使用DateTime::createFromFormat().来实现DateTime对象.但是,当我给这个函数一个不存在的日期时,它仍然有效,给我一个有效的DateTime对象,有一个有效的日期,这不是我给它的日期.

代码示例:

$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);

var_dump($date);

/*
object(DateTime)#284 (3) {
["date"]=>
string(19) "2011-01-03 10:01:20"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
*/
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?我真的需要一种检查日期有效性的方法.

谢谢.

编辑:

我刚刚找到原因,看看我的回答.

kro*_*ing 14

您必须使用DateTime::getLastErrors()哪个将包含错误The parsed date was invalid.

$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);
if( DateTime::getLastErrors()['warning_count'] > 0 ){
 //not a correct date
}else{
 //correct date
 print $date->format('Y-m-d');
}
Run Code Online (Sandbox Code Playgroud)


Cle*_*man 11

DateTime::createFromFormat当给定日期不可能时,不会抛出异常/返回false.它试图猜测预期的日期.

如果你给它'2010-01-32'(如Januar,32th),它将返回一个DateTime包含Februar 的对象,1日(Januar 31th + 1天).必须合乎逻辑......以某种奇怪的扭曲方式.

要检查有效性,您必须检查DateTime::getLastErrors()哪个包含警告,就像我的情况一样:

array(4) {
  ["warning_count"]=>
  int(1)
  ["warnings"]=>
  array(1) {
    [10]=>
    string(27) "The parsed date was invalid"
  }
  ["error_count"]=>
  int(0)
  ["errors"]=>
  array(0) {
  }
}
Run Code Online (Sandbox Code Playgroud)

此行为似乎来自PHP计算的UNIX时间戳,基于您提供的年份,月份和日期(即使日期无效).

  • “一定是合乎逻辑的……以某种奇怪的扭曲方式。” ==> 哦,我们在 PHP 中看到了很多。 (2认同)

Gla*_*vić 11

我找到了基于验证DateTime::getLastErrors()失败的示例,因此更好的解决方案是将输入日期与生成日期进行比较.

码:

function validateDate($date, $format = 'Y-m-d')
{
    $dt = DateTime::createFromFormat($format, $date);
    return $dt && $dt->format($format) == $date;
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

var_dump(validateDate('2012-02-28')); # true
var_dump(validateDate('2012-02-30')); # false

# you can validate and date/time format
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:99', 'H:i')); # false

# this is the example where validation with `DateTime::getLastErrors()` will fail
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false
Run Code Online (Sandbox Code Playgroud)