PHP DateTime::createFromFormat – Schaltjahr-Problem

Zeit/Datum Funktionen von PHP benutze ich seit langem und tendiere dazu, den Ergebnissen dieser Funktionen blind zu vertrauen. Desto unangenehmer war die Überraschung, die ich heute erlebt habe.

Für das Projekt brauchen wir einen Hashcode zu generieren, der Details eines Events verschlüsselt. Um diesen Hashcode möglichst kompakter zu halten, haben wie entschieden, für das Datum letzte 2 Zahlen vom Jahr und Nummer des Tages im Jahr zu übertragen (immer zweistellig, mit dem führenden 0, wenn nötig), z.B. für 1. Januar 2020 würde 20 fürs Jahr 2020 und 1 für 1.Januar übertragen.

Plötzlich (nämlich heute morgen) stellt der Kollege fest, dass das Datum im Hashcode irgendwie falsch berechnet wird.
Ich berechne dieses Datum folgendermaßen:

DateTime::createFromFormat('z Y', '61' . ' ' . '2020')

und bekomme:

DateTime Object
(
    [date] => 2020-03-03 19:54:59.000000
    [timezone_type] => 3
    [timezone] => UTC
)

Obwohl, wenn ich ein DateTime Objekt mit dem Datum 01.01.2020 erstelle und ein Zeitinterval 61 Tage addiere, bekomme ich 02.03.2020 (genauso habe ich das Problem gelöst).

Das Problem hat definitiv mit dem Schaltjahr zu tun. Um das zu überprüfen, führen wir folgenden Code aus:

print_r(DateTime::createFromFormat('z Y', '58' . ' ' . '2020'));

und bekommen:

DateTime Object
(
    [date] => 2020-02-28 19:54:59.000000
    [timezone_type] => 3
    [timezone] => UTC
)

Was passiert aber, wenn wir Tag des Jahres um 1 erhöhen:
print_r(DateTime::createFromFormat('z Y', '59' . ' ' . '2020'));

Das Ergebnis ist:

DateTime Object
(
    [date] => 2020-03-01 19:54:59.000000
    [timezone_type] => 3
    

In diesem Jahr müsste es 29.02.2020 sein, dieses Datum ist aber irgendwie „verschwunden“.