Hi
Derick and I are proposing the introduction of a new Time\Duration
class to represent “stop-watch” or “egg-timer” durations to improve the
developer experience for APIs taking a timeout. We are specifically
targeting PHP 8.6 for this RFC, since part of the motivation is
improving the API of the new “Polling API” that already landed in PHP
8.6 (https://wiki.php.net/rfc/poll_api) before the “backwards
compatibility” door closes with the feature freeze in two months.
This RFC is also intended to be a first part of a modernized date and
time API in PHP, while being useful on its own. To that extent and given
the deadline we hope to make, the proposed API is intentionally minimal
and focused on functionality that we are relatively certain to:
- Be correct, or
- be requirement for future additions that cannot later be added
without breaking compatibility.
We would therefore ask to keep the discussion focused on actual issues
rather than additional “convenience functionality” that might require
extensive discussion or thought.
All that said, you can find the RFC at:
https://wiki.php.net/rfc/duration_class. It hopefully includes all the
important explanation and also provides a rationale as to why we made
the design decisions we made.
Best regards
Tim Düsterhus
Hi
Derick and I are proposing the introduction of a new
Time\Duration
class to represent “stop-watch” or “egg-timer” durations to improve the
developer experience for APIs taking a timeout. We are specifically
targeting PHP 8.6 for this RFC, since part of the motivation is
improving the API of the new “Polling API” that already landed in PHP
8.6 (https://wiki.php.net/rfc/poll_api) before the “backwards
compatibility” door closes with the feature freeze in two months.This RFC is also intended to be a first part of a modernized date and
time API in PHP, while being useful on its own. To that extent and given
the deadline we hope to make, the proposed API is intentionally minimal
and focused on functionality that we are relatively certain to:
- Be correct, or
- be requirement for future additions that cannot later be added
without breaking compatibility.We would therefore ask to keep the discussion focused on actual issues
rather than additional “convenience functionality” that might require
extensive discussion or thought.All that said, you can find the RFC at:
https://wiki.php.net/rfc/duration_class. It hopefully includes all the
important explanation and also provides a rationale as to why we made
the design decisions we made.Best regards
Tim Düsterhus
Hi Tim,
Thank you for proposing this! I think it would be a good addition, and
a move in the right direction for a better built-in date-time stuff.
I do have some questions:
- Is there a reason the highest unit is seconds not hours?
- The RFC specifies
Duration::fromIso8601String, but there does not
seem to be a method to turn the duration itself back into an ISO 8601
string. is there a reason for that? - I think it would be nice to have methods that return the total
duration as a specific unit as a floating point, e.e.g.,
getTotalSeconds(), was this considered?
Also, i wanted to point out Psl\DateTime\Duration that is basically
the same thing:
https://github.com/php-standard-library/php-standard-library/blob/next/packages/date-time/src/Psl/DateTime/Duration.php#L37
which was modeled after Rust's std::time::Duration (
https://doc.rust-lang.org/beta/std/time/struct.Duration.html ) and
Java's Duration (
https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html ).
Cheers,
Seifeddine.
Hi
Am 2026-06-18 16:18, schrieb Seifeddine Gmati:
- Is there a reason the highest unit is seconds not hours?
The highest unit supported by the constructors is hours
(Duration::fromHours()). The internal representation uses a seconds +
nanoseconds pair for the reasons outlined in the design considerations,
similarly to Rust’s and Java’s Duration. 68 years on 32-bit systems and
21× the age of the universe on 64-bit systems should be plenty.
- The RFC specifies
Duration::fromIso8601String, but there does not
seem to be a method to turn the duration itself back into an ISO 8601
string. is there a reason for that?
The best reason there probably is “the proposed API is intentionally
minimal”.
There are probably also some decisions to be made for the
re-stringification into ISO-8601: Should it stringify straight into
sprintf("PT%d.%09dS", $seconds, $nanoseconds) or should it try to use
“as large units as possible” (i.e. minutes and hours). The correct
answer might depend on the use case and thus it's probably better to
move this decision to the PHP 8.7 cycle :-)
- I think it would be nice to have methods that return the total
duration as a specific unit as a floating point, e.e.g.,
getTotalSeconds(), was this considered?
Derick and I haven't discussed this, but the “minimal API” applies here
as well. Floating point versions we specifically left out (for now),
because we didn't want to go into the precision / rounding question. As
an example how many nanoseconds should 1.4 be? The internal
representation of that float is 1.3999999999999999.
Best regards
Tim Düsterhus
Derick and I haven't discussed this, but the “minimal API” applies here
as well. Floating point versions we specifically left out (for now),
because we didn't want to go into the precision / rounding question. As
an example how many nanoseconds should1.4be? The internal
representation of that float is1.3999999999999999.
I think precision doesn't matter here. The primary reason we added float
total methods in Psl was to be able to bridge a Duration object to other
APIs that accepted float $seconds ( mainly Revolt ), Rust and Java also
both offer the floating point methods, and i think they make sense. Could
be added in the future though.
Another nitpick: I think the namespace should be DateTime if this is
supposed to be start of a new API that covers both date and time, so we
don't end up with two namespace later (which will share alot of things back
and forth).
Cheers,
Seifeddine.
Hi
Am 2026-06-18 17:20, schrieb Seifeddine Gmati:
[…] float […] Could be added in the future though.
Yes, my reply was not intended to be a “we are definitely against
floats”, but more a “floats are not completely obvious to handle, so we
rather think about the consequences later”.
Another nitpick: I think the namespace should be
DateTimeif this is
supposed to be start of a new API that covers both date and time, so we
don't end up with two namespace later (which will share alot of things
back
and forth).
The Time namespace matches that of most references we looked at.
std::time in Rust, java.time in Java, time in Golang. JavaScript
calling it Temporal is the “odd person out”. Personally I also think of
“Time” as the generic concept that also includes “Dates”.
Thus the upcoming classes to also handle “calendar dates” and “time as
shown on a clock” would be appropriately located in the Time
namespace. Java uses java.time.ZonedDateTime for the closest
equivalent to PHP’s existing DateTimeImmutable (and
java.time.Instant for timezone-less points in time). See
https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html#package.description
for a description of the class hierarchy and relationships.
Best regards
Tim Düsterhus
Hi Tim,
The only one concern I see is the method fromIso8601String.
Unfortunately the PHP has this weird constant that is called DATE_ISO8601
https://www.php.net/manual/en/class.datetimeinterface.php#datetimeinterface.constants.iso8601,
that is not in fact proper standard.
I wanted to deprecate it few years ago, but the push back from community
was strong, so I did suggest only deprecation of DATE_RFC7231.
So what kind of format this method will except, standard ISO, or PHP's
version of ISO? Maybe it's worth to find another name?
Kind regards,
Jorg
Hi
Am 2026-06-18 18:33, schrieb Jorg Sowa:
So what kind of format this method will except, standard ISO, or PHP's
version of ISO? Maybe it's worth to find another name?
The method will accept a ISO-8601 “Period” string, just like
DateInterval::__construct() does. The only restriction is that period
strings accepted by the Time\Duration class may only contain the “time”
components. In simplified terms: The given string must start with PT.
The format strings you are thinking about are those to format
date-times, which is a different concern and which will become relevant
when classes to represent dates and times are added in the future. Given
those are intended to fix the issues of the current API, I expect them
to exactly follow the relevant standards when referring to a standard.
Just like the URI parsers in the new URI extension follow the WHATWG and
RFC 3986 standards - and any difference is considered a bug. Given that
namespaces for PHP’s standard library are a relatively new thing, this
luckily allows us to fix issues by building an entirely new,
well-designed API without breaking backwards compatibility and without
needing to come up with weird names to avoid conflicts. This worked well
for the new random API in 8.2, the new DOM API in 8.4 and the new URI
API in 8.5 and we hope to continue that with the new date API starting
in 8.6.
Best regards
Tim Düsterhus