I wonder why this php code gives incorrect output value.
dd(new \DateTime("1397/02/29", new \DateTimeZone('Asia/Tehran')));
It outputs below object:
DateTime @-18076965944 {#1256 ▼
date: 1397-03-01 00:00:00.0 Asia/Tehran (+03:25)
}
As you see the date is incorrect and must be 1397-02-01
. The output for values 1397/02/30 && 1397/02/31
is incorrect also.
Can anyone help please. thanks.
PHP store date object internal as 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
But DateTime init have no validating and only converts given date string to timestamp. https://github.com/php/php-src/blob/master/ext/date/php_date.c#L2647
Before creating date object you should check it using http://php.net/manual/en/function.checkdate.php
var_dump(
checkdate(2,20,1000), // bool(true)
checkdate(2,30,1000) // bool(false)
);
The DateTime leap year code applies the Gregorian calendar rules, and they do not work for the Persian calendar.
The "divide by 4 but not 100 except 400" rule is not valid for Persian calendar, which follows a different algorithm:
https://www.timeanddate.com/date/iran-leap-year.html
Basically, you cannot use DateTime
for Persian dates. See also here. You might perhaps adapt some other code.
Update: actually, it appears different calendars and sources do not agree on leap years. Jalali has 1397 as a leap year but Persian calendar does not?
Thank you everybody for your responses.
As i was going to convert a Jalali
date to a Gregorian
date, i was trying to make a PHP DateTime
object of my Jalali
date string ("1397/02/29")
and then convert the date object to the Gregorian
date object using this package. I fixed the issue by directly converting my Jalali
date string to what i want using morilog/jalali like below:
$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;
Thank you all again.