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 неверно также.

Может кто-нибудь помочь, пожалуйста.
Благодарю.

0

Решение

PHP хранит объект даты внутри структуры
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)
);
0

Другие решения

Код високосного года DateTime применяет правила григорианского календаря, и они не работают для персидского календаря.

Правило «делить на 4, но не на 100, кроме 400» недопустимо для персидского календаря, который следует другому алгоритму:

https://www.timeanddate.com/date/iran-leap-year.html

В принципе, вы не можете использовать DateTime для персидских дат. Смотрите также Вот. Вы могли бы, возможно, адаптировать какой-то другой код.

Обновить: на самом деле, появляются разные календари и источники не согласен в високосные годы. Джалали имеет високосный 1397 год, а персидский календарь — нет?

1

Спасибо всем за ваши ответы.

Как я собирался преобразовать Jalali дата для Gregorian дата, я пытался сделать PHP DateTime объект моего Jalali строка даты ("1397/02/29") а затем преобразовать объект даты в Gregorian использование объекта date этот пакет. Я исправил проблему, напрямую конвертировав 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;

Спасибо всем еще раз.

0
По вопросам рекламы [email protected]