2016-01-04 2 views
0

Работал с валидатором Laravel, и я заметил странную проблему с подтверждением дат.php date_parse_from_format() не распознает разницу между y и Y

Laravel date_format зависит от метода php date_parse_from_format. Однако этот метод, по-видимому, не распознает разницу между y и Y, когда вы задаете формат d/m/Y. Поэтому, если вы переходите в 01/01/15 или 01/01/2015, сидите без ошибок. Вы ожидали бы, что первая ошибка, или, по крайней мере, я бы это сделал.

Если вы изменили формат на 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 как 1 января 2020 года и будет генерировать ошибку, в которой он обнаружил конечные данные.

Редактировать

При переходе к ОО 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 

В РНР 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

Смежные вопросы