Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my IntlDateFormatter formatting the wrong day? [duplicate]

Tags:

php

datetime

intl

I am trying to format a date from the past but apparently fail to do so.

The issue is, that the date is not just off by a few hours (which could be due to different timezones), but instead it is off by 5 days.

This is my example code:

<?php

$locale = "de";
$intlTimezone = \IntlTimeZone::createDefault();
$dateTimezone = $intlTimezone->toDateTimeZone();
$calendar = new \IntlGregorianCalendar($intlTimezone, $locale);
$dateFormatter = \IntlDateFormatter::create($locale, 2, -1, $intlTimezone, $calendar, "dd.MM.y");

$time = DateTimeImmutable::createFromFormat("Y-m-d", "978-12-27", $dateTimezone);
var_dump($time);
var_dump($time->format("d.m.Y"));
var_dump($dateFormatter->format($time));

You can see it on 3v4l.org here: https://3v4l.org/tXVgn

This is the output:

object(DateTimeImmutable)#5 (3) {
    ["date"]=>
    string(26) "0978-12-27 14:31:03.000000"
    ["timezone_type"]=>
    int(2)
    ["timezone"]=>
    string(3) "CET"
}
string(10) "27.12.0978"
string(9) "22.12.978"

The last value seems wrong. Please also note, that PHP <= 7.0.33 fails to format it and returns false.

like image 727
apfelbox Avatar asked Oct 20 '25 14:10

apfelbox


1 Answers

The createFromFormat function seems to use the prolectic Gregorian calendar, which applies the calendar we currently use to old dates. The date format seems to use the Julian calendar which is the one that was actually used. For 978 the difference between the two is 5 days.

Strangely I find nothing in documentation that would specify which calendar is used by which class or which date is considered as the cut off between the two calendar systems.

like image 53
Joni Avatar answered Oct 22 '25 04:10

Joni