Привет, мне кажется, у меня проблемы с тем, чтобы метод datetime работал так, как ожидалось? Может, я что-то делаю неправильно?
// Passes OK $dateTime = DateTime::createFromFormat('d/m/Y', '12/12/2012' ); var_dump($dateTime); // should fail but returns - 2016-09-25 $dateTime = DateTime::createFromFormat('d/m/Y', '56/56/2012' ); var_dump($dateTime); // correctly returns False $dateTime = DateTime::createFromFormat('d/m/Y', '56/56/fail' ); var_dump($dateTime); // should fail but returns 2019-08-29 09:58:10 $dateTime = DateTime::createFromFormat('m/d/Y', '90/90/2012' ); var_dump($dateTime);
Дело в DateTime::createFromFormat
заключается в том, что есть два типа неожиданного ввода, который он распознает: тип, который генерирует ошибки, и тип, который генерирует предупреждения.
Ввод, такой как '56/56/fail'
вызывает ошибку, поэтому возвращается false
и все хорошо. Тем не менее, '56/56/2012'
дает не ошибку, а предупреждение, и фактически анализируется как 56-й день 56-го месяца 2012 года. С 2012 года не было 56 месяцев, PHP внутренне меняет это на 2016 + 8 месяцев = Август 2016. И поскольку в этом месяце нет 56 дней, у нас есть еще одна компенсация до сентября 2016 года (56-31) дней = 25 сентября 2016 года. Поэтому, когда это неожиданно, это на самом деле правильно.
Если вы хотите запретить эту автоматическую настройку, вы должны обернуть фабричный метод DateTime::getLastErrors
и использовать DateTime::getLastErrors
качестве ссылки:
$dateTime = DateTime::createFromFormat('d/m/Y', '56/56/2012'); $errors = DateTime::getLastErrors(); if (!empty($errors['warning_count'])) { echo "Strictly speaking, that date was invalid!\n"; }
Смотрите в действии .
На самом деле это правильно: например, если вы создаете дату с 2012/04/31 (неверная дата), PHP возвращает 2012/05/01 (первый день может)!
Это делается за кулисами
PHP – странный зверь (мягко говоря). 56/56/2012
приводит к тому, что все дополнительные месяцы и дни добавляются к дате до тех пор, пока она не станет правильной (бог знает только логику этого).