-
Notifications
You must be signed in to change notification settings - Fork 79
Description
Summary
If PHP is configured with a non-UTC timezone, this library ends up caching objects that should not be cached when going from summer time to winter time.
Details
This library uses new \DateTime('-1 seconds')
as an expiry timestamp for objects that should not be cached.
E.g. in src/Strategy/PrivateCacheStrategy.php#L112
:
return new CacheEntry($request, $response, new \DateTime('-1 seconds'));
If PHP is configured with a non-UTC time zone, this breaks when going from summer time to winter time.
For example, both UTC time "2024-10-27 00:00:56" and "2024-10-27 01:00:56" was "2024-10-27 02:00:56" in timezone Europe/Berlin:
$ TZ=Europe/Berlin date -d '2024-10-27T00:00:56 +00:00'
Sun 27 Oct 02:00:56 CEST 2024
$ TZ=Europe/Berlin date -d '2024-10-27T01:00:56 +00:00'
Sun 27 Oct 02:00:56 CET 2024
The PHP DateTime
class does not differentiate between these timestamps. However, when calling $ts->getTimestamp()
it will always return the last value, even if it is in the future.
This library uses the $ts->getTimestamp()
method to calculate a TTL for the object, which will then indicate that an object with an expiry of -1 seconds
will be valid for nearly one hour.
Here is an example script that shows the problem:
<?php
$ts = new \DateTime("-1 seconds");
echo '$ts = ' . var_export($ts, true) . "\n";
echo '$ts->getTimestamp() = ' . $ts->getTimestamp() . "\n";
$ttl = $ts->getTimestamp() - time();
echo '$ttl = ' . $ttl . "\n";
Run this script during the transition from summer time to winter time using a non-UTC timezone to see the problem.
For example, using the faketime
command and the Europe/Berlin
time zone:
$ faketime '2024-10-27 00:00:56 +00:00' php -d date.timezone=Europe/Berlin datetime-timestamp.php
$ts = \DateTime::__set_state(array(
'date' => '2024-10-27 02:00:55.936087',
'timezone_type' => 3,
'timezone' => 'Europe/Berlin',
))
$ts->getTimestamp() = 1729990855
$ttl = 3599