PHP DateTime принимает недопустимую дату
У меня возникли проблемы с использованием класса PHP DateTime
и, более конкретно, DateTime::createFromFormat()
.
Я получаю дату из строки, а затем пытаюсь инициализировать объект DateTime, используя DateTime::createFromFormat()
. Но когда я даю этой функции дату, которая не может существовать, она все еще работает, возвращая мне действительный объект DateTime
с допустимой датой , который не является датой, которую я дал ей.
Пример кода:
$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);
var_dump($date);
/*
object(DateTime)#284 (3) {
["date"]=>
string(19) "2011-01-03 10:01:20"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
*/
Любые идеи? Мне действительно нужен способ проверить правильность даты.
Спасибо.
Изменить:
Я только что нашел, почему, см. мой ответ.
Ответы
Ответ 1
DateTime::createFromFormat
не генерирует исключение/возвращает false, когда данная дата невозможна. Он пытается угадать ожидаемую дату.
Если вы дадите ему '2010-01-32'
(как в Januar, 32), он вернет объект DateTime
, содержащий Februar, 1st (Januar 31th + 1 day). Должен быть логичным... каким-то странным скрученным способом.
Чтобы проверить правильность, вы должны проверить DateTime::getLastErrors()
, который содержит предупреждение, например, для моего случая:
array(4) {
["warning_count"]=>
int(1)
["warnings"]=>
array(1) {
[10]=>
string(27) "The parsed date was invalid"
}
["error_count"]=>
int(0)
["errors"]=>
array(0) {
}
}
Это похоже на временную метку UNIX, которую PHP вычисляет на основе года, месяца и даты, которые вы даете (даже если дата недействительна).
Ответ 2
Вы должны использовать DateTime::getLastErrors()
, который будет содержать ошибку The parsed date was invalid
.
$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);
if( DateTime::getLastErrors()['warning_count'] > 0 ){
//not a correct date
}else{
//correct date
print $date->format('Y-m-d');
}
Ответ 3
Я нашел пример, где проверка на основе DateTime::getLastErrors()
завершится неудачно, поэтому лучшим решением было бы сравнить введенную дату с сгенерированной датой.
код:
function validateDate($date, $format = 'Y-m-d')
{
$dt = DateTime::createFromFormat($format, $date);
return $dt && $dt->format($format) == $date;
}
Пример использования:
var_dump(validateDate('2012-02-28')); # true
var_dump(validateDate('2012-02-30')); # false
# you can validate and date/time format
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:99', 'H:i')); # false
# this is the example where validation with `DateTime::getLastErrors()` will fail
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false
Ответ 4
Найдите checkdate() в документации php. Это поможет вам:)
Ответ 5
Вы можете сделать это:
DateTime::getLastErrors()
Ответ 6
изменить
$date = DateTime::createFromFormat('Y-m-d', $badDate);
в
$date = DateTime::createFromFormat('Y-d-m', $badDate);
Ваш данный формат неверен, вы правильно перемешали дни и месяцы...
Чтобы понять, что находится за магическим расчетом дат, читайте эту очень хорошую статью Дерика Ретанса и все комментарии;)