PHP DateTime дает неверное значение
Интересно, почему этот код PHP дает неправильное значение вывода.
dd(new \DateTime("1397/02/29", new \DateTimeZone('Asia/Tehran')));
Выводит ниже объекта:
DateTime @-18076965944 {#1256 ▼
date: 1397-03-01 00:00:00.0 Asia/Tehran (+03:25)
}
Как видите, дата неверна и должна быть 1397-02-01
, Вывод значений 1397/02/30 && 1397/02/31
неверно также.
Может кто-нибудь помочь, пожалуйста. Благодарю.
3 ответа
PHP хранит объект даты внутренний как struct https://github.com/php/php-src/blob/master/ext/date/php_date.h#L137 https://github.com/php/php-src/blob/master/ext/date/lib/timelib.h#L204
Но инициализация DateTime не имеет проверки и преобразует только заданную строку даты в метку времени. https://github.com/php/php-src/blob/master/ext/date/php_date.c#L2647
Перед созданием объекта даты вы должны проверить его, используя http://php.net/manual/en/function.checkdate.php
var_dump(
checkdate(2,20,1000), // bool(true)
checkdate(2,30,1000) // bool(false)
);
Код високосного года DateTime применяет правила григорианского календаря, и они не работают для персидского календаря.
Правило "делить на 4, но не на 100, кроме 400" недопустимо для персидского календаря, который следует другому алгоритму:
https://www.timeanddate.com/date/iran-leap-year.html
В принципе, вы не можете использовать DateTime
для персидских дат. Смотрите также здесь. Возможно, вы можете адаптировать другой код.
Обновление: на самом деле, появляются разные календари и источники не сходятся в високосных годах. У Джалали 1397 год как високосный, а у персидского календаря нет?
Спасибо всем за ваши ответы.
Как я собирался преобразовать Jalali
дата для Gregorian
дата, я пытался сделать PHP DateTime
объект моего Jalali
строка даты ("1397/02/29")
а затем преобразовать объект даты в Gregorian
дата объекта с помощью этого пакета. Я исправил проблему, напрямую конвертировав Jalali
Строка даты, что я хочу, используя morilog / jalali, как показано ниже:
$jalali_date = explode("/", request()->to);
$gregorian_date_time = \jDateTime::toGregorianDate($jalali_date[0], $jalali_date[1], $jalali_date[2])->setTime(23, 55)->format("Y-m-d H:i");
return $gregorian_date_time;
Спасибо всем еще раз.