Running the following script:
var_dump(
(DateTimeImmutable::createFromFormat(
format : 'Y-m-d H:i:s',
datetime: '2120-10-03 07:00:00',
timezone: new DateTimeZone('Europe/Zurich')
))->getTimestamp()
);
In PHP 8.2 produces the unix epoch timestamp 4757374800
, which is correct.
When this script is executed on a server whose PHP version is 5.6, the value we get is incorrect 4757378400
(one hour too late).
Why does this happen?
Same happens if we compute the unix epoch second via:
date_default_timezone_set('Europe/Zurich');
$timestamp = strtotime('2120-10-03 07:00:00 Europe/Zurich');
echo $timestamp;
Key clues:
Looking at the PHP 8.1 changelog we do indeed find this:
Fixed bug #64992 (dst not handled past 2038).
From the comments on that ticket, the underlying problem was actually that the Olsen/IANA TimezoneDB didn't handle projected future DST transitions past the 32-bit cut-off date, so PHP had to wait until that was fixed first.
Of course, as noted by some of the comments there, there's actually no guarantee which result will be correct in 100 or even 20 years time, because Switzerland might well follow suit if the EU goes ahead with long-discussed plans to end DST changes, or could completely change offset for some other reason.
The issue you ran into with MySQL is likely a different Year 2038 bug, where it is using a 32-bit timestamp and catching out of range values.