2016-01-04 39 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

相關問題