Re: [RFC] Time\Instant and Time\Clock

From: Date: Thu, 01 Oct 2026 17:16:05 +0000
Subject: Re: [RFC] Time\Instant and Time\Clock
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-132761@lists.php.net to get a copy of this message
Hi thank you Andreas, that mostly matches what I would have answered myself. I'll add my own nuance in a separate reply to Mirco directly. On 2026-10-01 17:57, Andreas Heigl wrote:
But all that is obsoleted and irrelevant in the end as the Instant is based on the epoch which is based on UTC minus leap-seconds. At least as far as I understood Tim.
Yes, or “POSIX time”, which avoids the overloaded term UTC that could also refer to the UTC timezone. Timezones reintroduce “date and time” as a concept, which is not relevant to a point in time.
I have demonstrated it is impossible to write an adapter. Given the constraint that only the PSR-20 MyClock class can be changed, call-sites must not be adjusted. Also the purpose of a PSR-20 Clock is to never call new DateTimeImmutable() or time() anymore, so the assumption there are new DateTimeImmutable() calls that can be adapted is incorrect.
An adapter does never need to implement both interfaces. In essence an adapter only needs to implement "the other" interface. A ClockAdapter uses a ClockInterface to create an Instant whereas a ClockInterfaceAdapter uses a Clock to create a DateTime. 2 classes that seem rather straight forward.
Indeed. Here's an example implementation for both directions. The NativeToPsr20 adapter truncates to microseconds and needs to “invent” a timezone. The opinionated choices made there should be correct for the vast majority of users:
    final readonly class Psr20ToNative implements \Time\Clock
    {
        public function __construct(
            private \Psr\Clock\ClockInterface $clock,
        ) {}
        public function now(): \Time\Instant
        {
            return $this->clock->now()->toInstant();
        }
    }
    final readonly class NativeToPsr20 implements \Psr\Clock\ClockInterface
    {
        public function __construct(
            private \Time\Clock $clock,
            private \DateTimeZone $timezone = new \DateTimeZone('UTC'),
        ) {}
        public function now(): \DateTimeImmutable
        {
            $now = $this->clock->now();
            return \DateTimeImmutable::createFromTimestamp($now->getUnixTimestamp())
                ->setMicrosecond(\intdiv($now->getNanoseconds(), 1_000))
                ->setTimezone($this->timezone);
        }
    }
Best regards Tim Düsterhus

« previous php.internals (#132761) next »