PHP DateTime接受无效日期

时间:2011-04-04 08:15:04

标签: php datetime date

我无法使用PHP DateTime类,更具体地说是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"
}
*/

有什么想法吗?我真的需要一种检查日期有效性的方法。

谢谢。

编辑:

我刚刚找到了原因,请参阅我的回答。

6 个答案:

答案 0 :(得分:13)

您必须使用包含错误DateTime::getLastErrors()的{​​{1}}。

The parsed date was invalid

答案 1 :(得分:10)

当给定日期不可能时,

DateTime::createFromFormat不会抛出异常/返回false。它试图猜测预期的日期。

如果你给它'2010-01-32'(如Januar,32th),它将返回一个包含Februar的DateTime对象,第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) {
  }
}

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

答案 2 :(得分:10)

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

代码:

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

使用示例:

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

答案 3 :(得分:3)

在php文档中查找checkdate()函数。它会帮助你:))

答案 4 :(得分:0)

你可以这样做:

DateTime::getLastErrors()

答案 5 :(得分:-1)

更改

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

进入

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

您的给定格式错误,您正好混淆了几天和几个月......

要了解日期的神奇计算背后的内容,请阅读非常good article by Derick Rethans及所有评论;)