-
Couldn't load subscription status.
- 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 2024The 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