Tim Düsterhus and Derick Rethans just proposed the next piece of PHP's new date and time API. The Time\Instant and Time\Clock RFC adds a class for a single point in time and a clock interface you can swap out in tests. They opened the discussion on internals on September 21, targeting PHP 8.7.
It follows Time\Duration, which the same pair got into PHP 8.6. Duration tells you how long something took. Instant tells you when it happened.
What It Does
Time\Instant is a point in time with nanosecond precision and no timezone. Today you'd reach for an int from time(), which drops anything under a second and doesn't say what unit it's in, or a DateTimeImmutable, which carries a timezone and a calendar along with it.
Here is the RFC's own example:
use Time\Clock\SystemClock; use Time\Instant; $clock = new SystemClock(); $now = $clock->now(); $moonLanding = Instant::fromIso8601DateTimeString('1969-07-20T20:17:40Z'); printf("It's been %d seconds since the moon landing\n", $moonLanding->until($now)->seconds);
You create an instant from a Unix timestamp, in seconds or milliseconds, or from an ISO-8601 string, which has to include a zone offset. From there you can add() or sub() a Duration, get the Duration between two instants with until(), and compare instants with <, > and <=>. Formatting isn't included, since that needs a timezone, and the RFC leaves it to a later class.
A few design choices worth knowing:
- Leap seconds are ignored, the same as on most operating systems.
- The internal representation isn't public. The Unix timestamp is one way in and out, not the primary format.
- The exact range is unspecified, but it covers at least everything
DateTimeImmutablecan represent. - On 32-bit builds, the Unix timestamp methods only cover the years 1901 to 2038.
A Clock You Can Swap Out
The other half is a Time\Clock interface with a single now() method, and a Time\Clock\SystemClock that reads the system clock. The point is testing. Code that asks a clock for the time can be handed a fake one instead:
final class TokenValidator { public function __construct( private readonly Clock $clock, private readonly Duration $validityPeriod, ) {} public function isValid(Instant $issuedAt): bool { return $this->clock->now() < $issuedAt->add($this->validityPeriod); } }
The RFC doesn't ship any test clocks. It says the ways people build them vary too much, so those stay in userland. It also describes Time\Clock as a direct replacement for PSR-20's ClockInterface, except that it returns an Instant instead of a DateTimeImmutable.
What Internals Is Asking
The thread has about ten replies so far:
- PSR-20. Andreas Heigl worried that two clock interfaces returning different types will confuse people. Düsterhus replied that the new API is a deliberate clean break, and that an adapter can serve both interfaces during a migration. Adding
fromInstant()andtoInstant()toDateTimeImmutablehas also been discussed. - Naming and
now(). Seifeddine Gmati suggested calling the classSystemTime, as Rust does, and savingInstantfor a future monotonic clock. Gmati also asked for a staticnow()shortcut and built-in frozen and offset clocks. Replying personally rather than as an RFC author, Düsterhus pointed to JavaScript's Temporal and Java'sjava.time, which both useInstantfor this. - Range and roadmap. Larry Garfield is broadly in favor, but asked why the range is unspecified, since an API that can't promise next week is in range is hard to trust. Garfield also asked for a written roadmap for the rest of the date and time API. Clarifying the range is already listed under the RFC's open issues.
The RFC was also updated on September 23 to say its serialization format will be portable between 32-bit and 64-bit PHP.
What It Means for Your Code
Nothing breaks. The RFC adds three new symbols in the Time\ namespace, which was reserved when Duration was accepted. Extensions may start accepting an Instant alongside Unix timestamps and DateTimeInterface objects.
What Happens Next
There's no vote scheduled yet. Düsterhus noted there are several months before the next feature freeze, and the RFC already lists a timezone class, other epochs, and a new monotonic clock API as future work.
Read the full proposal in the RFC, follow the thread on externals.io, and track its status on the PHP News RFC tracker.