php date_parse_from_format()无法识别y和Y

时间:2016-01-04 12:16:11

标签: php validation date laravel

一直在使用Laravel验证器,我发现了验证日期的奇怪问题。

Laravel date_format依赖于php date_parse_from_format方法。但是,当您将格式设置为d / m / Y时,此方法似乎无法识别y和Y之间的差异。因此,如果您在2015年1月1日或2015年1月1日通过,则解析时都没有错误。你希望前者出错,或者至少我愿意。

如果将格式更改为d / m / y,则按预期工作。那是2015年1月1日的通行证,2015年1月1日失败。

我有兴趣知道是否有其他人对此有任何想法以及我是否错过了一些明显的事情。这可能会对PHP和Laravel产生影响。

注意我使用的是php 5.6.16,我的输出如下......

string 'd/m/Y' (length=5)
string '01/01/15' (length=8)

array (size=12)
  'year' => int 15
  'month' => int 1
  'day' => int 1
  'hour' => boolean false
  'minute' => boolean false
  'second' => boolean false
  'fraction' => boolean false
  'warning_count' => int 0
  'warnings' => 
    array (size=0)
      empty
  'error_count' => int 0
  'errors' => 
    array (size=0)
      empty
  'is_localtime' => boolean false

string 'd/m/Y' (length=5)
string '01/01/2015' (length=10)

array (size=12)
  'year' => int 2015
  'month' => int 1
  'day' => int 1
  'hour' => boolean false
  'minute' => boolean false
  'second' => boolean false
  'fraction' => boolean false
  'warning_count' => int 0
  'warnings' => 
    array (size=0)
      empty
  'error_count' => int 0
  'errors' => 
    array (size=0)
      empty
  'is_localtime' => boolean false

string 'd/m/y' (length=5)
string '01/01/15' (length=8)

array (size=12)
  'year' => int 2015
  'month' => int 1
  'day' => int 1
  'hour' => boolean false
  'minute' => boolean false
  'second' => boolean false
  'fraction' => boolean false
  'warning_count' => int 0
  'warnings' => 
    array (size=0)
      empty
  'error_count' => int 0
  'errors' => 
    array (size=0)
      empty
  'is_localtime' => boolean false

string 'd/m/y' (length=5)
string '01/01/2015' (length=10)

array (size=12)
  'year' => int 2020
  'month' => int 1
  'day' => int 1
  'hour' => boolean false
  'minute' => boolean false
  'second' => boolean false
  'fraction' => boolean false
  'warning_count' => int 0
  'warnings' => 
    array (size=0)
      empty
  'error_count' => int 1
  'errors' => 
    array (size=1)
      8 => string 'Trailing data' (length=13)
  'is_localtime' => boolean false

输出数据的示例代码是......

$format = 'd/m/Y';
var_dump($format);
$date = '01/01/15';
var_dump($date);
var_dump(date_parse_from_format($format, $date));

$format = 'd/m/Y';
var_dump($format);
$date = '01/01/2015';
var_dump($date);
var_dump(date_parse_from_format($format, $date));

etc...

1 个答案:

答案 0 :(得分:1)

这是预期的行为,而不是错误。

15将被解释为0015 A.D.,然后,d/m/Y将能够成功解析它。

另一种可能的结果:

$date3 = date_parse_from_format('d/m/y', '01/01/2015');
var_dump($date3);

这将产生:

array(12) {
  ["year"]=>
  int(2020)
  ["month"]=>
  int(1)
  ["day"]=>
  int(1)
  ["hour"]=>
  bool(false)
  ["minute"]=>
  bool(false)
  ["second"]=>
  bool(false)
  ["fraction"]=>
  bool(false)
  ["warning_count"]=>
  int(0)
  ["warnings"]=>
  array(0) {
  }
  ["error_count"]=>
  int(1)
  ["errors"]=>
  array(1) {
    [8]=>
    string(13) "Trailing data"
  }
  ["is_localtime"]=>
  bool(false)
}

注意errors索引。它将成功地将01/01/20解释为2020年1月1日,并将生成错误,它发现了尾随数据。

修改

当您切换到OO API DateTime::createFromFormat时,默认行为会更改,会按预期工作

$date3 = DateTime::createFromFormat('d/m/y', '01/01/2015');
var_dump($date3); // will yield FALSE, as it does not recognize the intput

从PHP 5.3.9开始,我们可以使用行为与+类似的date_parse_from_format标志:

$date3 = DateTime::createFromFormat('d/m/y+', '01/01/2015');
var_dump($date3); // will yield a DateTime object

您可以使用DateTime::getLastErrors()获取生成的错误。

请参阅docs