【问题标题】:Validating Year with DateTime::createFromFormat使用 DateTime::createFromFormat 验证年份
【发布时间】:2013-05-01 16:24:39
【问题描述】:

我有这段代码用于在使用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

【问题讨论】:

  • 它不会静默失败:3v4l.org/bap8p
  • @Gordon thx for 3v4l.org,看起来很酷!
  • 请注意,11 月只有 30 天 ;)
  • @Gordon 3v4l.org 看起来很漂亮3v4l.org/muLLh
  • 作为一种解决方法,您可以先使用正则表达式模式检查正确的格式,然后使用日期时间检查正确的值。

标签: php datetime


【解决方案1】:

来自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');
}

【讨论】:

    【解决方案2】:
    $date = DateTime::createFromFormat('d/m/Y', $dateofbirth);
    

    [...]

    这个日期有效

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

    但是这个失败了

    $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,这可能会造成严重的用户混淆。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 2021-08-25
      • 1970-01-01
      • 2017-11-01
      • 2012-04-24
      • 1970-01-01
      • 2011-07-20
      相关资源
      最近更新 更多