2016-01-04 15 views
0

与Laravel验证器一起工作,我发现验证日期有一个奇怪的问题。php date_parse_from_format()无法识别y和Y之间的差异

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

如果将格式更改为d/m/y,则其按预期工作。那是01/01/15通行证和01/01/2015通行证失败。

我很想知道是否有其他人对此有任何想法,以及我是否漏掉了明显的东西。这可能对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... 
+0

你最近怎么解析你的日期?你能告诉我们一些代码吗? – tptcat

+3

可能是因为'15',即'15AD'是可以假定为“0015”的有效年份。 –

+0

增加了一些代码。我也假定它涉及到公元15年,但Y暗示着yyyy。所以当然不应该在这些基础上解析。它预计四位数字? – RobDW1984

回答

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

+0

我测试了'd/m/y'并获得了预期的结果,请参阅我的输出结果。这里对我的问题是php中的文档说Y应该匹配四位数字。所以只有0015应该匹配,而15应该错误。 http://php.net/manual/en/datetime.createfromformat.php – RobDW1984

相关问题