使用DateTime::createFromFormat验证年份

3

我有一段代码用于验证正确格式的日期,然后再使用DateTime::createFromFormat()将其提交到数据库插入。我期望日期格式能够从“DD/MM/YYYY”转换为“YYYY-MM-DD”,否则就会出现错误。

$dateofbirth = trim($_POST['dateofbirth']);
$date = DateTime::createFromFormat('d/m/Y', $dateofbirth);

$date_errors = DateTime::getLastErrors();
    var_dump($date_errors);
if ($date_errors['warning_count'] + $date_errors['error_count'] > 0) {
    $dobError = 'Date '.$dateofbirth.' is not a valid DD/MM/YYYY format.';
    $hasError = true;
} else {
    $mysql_dob = $date->format('Y-m-d');
}
error_log($dateofbirth.' -> '.$mysql_dob);

这个日期可行。
 $dateofbirth = '30/11/1980'; => 1980-11-30

但是这个会默默失败。
 $dateofbirth = '30/11/80'; => 0080-11-30

自从我期望被通知缺失的世纪数字以来,我已经阅读了格式规则并使用了大写的“Y”,这应该确保有一个4位数的年份。你有什么想法我做错了什么?
编辑:
1-根据OneTrickPony的评论更正测试日期。
2-我添加了$date_errors变量的var_dump。由于格式是“d/m/Y”,输入是“30/11/80”,所以我期望会出现错误或警告,但实际上没有。
array(4) {
  ["warning_count"]=>
  int(0)
  ["warnings"]=>
  array(0) {
  }
  ["error_count"]=>
  int(0)
  ["errors"]=>
  array(0) {
  }
}
30/11/80 -> 0080-11-30

3
它不会悄悄失败:http://3v4l.org/bap8p - Gordon
@Gordon,感谢3v4l.org,看起来很酷! - Marcel Gwerder
1
请注意,11月只有30天 ;) - nice ass
@Gordon 3v4l.org 看起来相当不错 http://3v4l.org/muLLh - emeraldjava
1
作为一种解决方法,您可以首先使用正则表达式模式检查正确的格式,然后再使用DateTime检查正确的值。 - Gordon
2个回答

0
DateTime::createFromFormat的文档中返回的内容。

http://www.php.net/manual/en/datetime.createfromformat.php

Returns a new DateTime instance or FALSE on failure.

因此,与其检查getLastErrors,您应该检查$date === false

将您的错误检查更改为:

if ($date === false) {
    $dobError = 'Date '.$dateofbirth.' is not a valid DD/MM/YYYY format.';
    $hasError = true;
} else {
    $mysql_dob = $date->format('Y-m-d');
}

-1
$date = DateTime::createFromFormat('d/m/Y', $dateofbirth);

[...]

This date works

$dateofbirth = '30/11/1980'; => 1980-11-30

but this one fail silently

$dateofbirth = '30/11/80'; => 0080-11-30
根据DateTime::createFromFormat()手册页面,您提供的格式非常明确地寻找一个四位数年份。它将“80”解析为公元80年而不是1980年。
要接受两位数的年份,您需要使用小写的y而不是大写的Y。但是,这也将不接受四位数的年份。
您的选择是:
  1. 在遇到日期验证代码之前验证用户输入的正确字符串长度。
  2. 使用字符串长度确定所使用的格式
  3. 使用正则表达式检查年份的长度并相应更改格式
  4. 如果您正在使用正则表达式,则可以使用checkdate()
  5. 停止接受非常奇怪、非标准的DD/MM/YYYY格式的日期。在常用斜杠的情况下,预期的格式实际上是MM/DD/YYYY,这可能会导致用户混淆。

DD/MM/YYYY并不是“非常奇怪”的日期格式。实际上,它是更为常见的日期格式之一(参见https://en.wikipedia.org/wiki/Date_format_by_country)。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接