Re: [RFC] Duration class
| From: | John Bafford | Date: | Mon, 22 Jun 2026 15:35:06 +0000 |
| Subject: | Re: [RFC] Duration class | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131460@lists.php.net to get a copy of this message | ||
Hi all,
> On Jun 22, 2026, at 03:01, marc@mabe.berlin wrote:
>
> I have looked up the implementations of other Duration classes you mentioned - Go, Java, Rust -
> none of them have such kind of negative flag.
>
> * Go (https://pkg.go.dev/time#Duration)
> Just int64 of nanoseconds - negative durations are a negative number
>
> * Java
> (https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/java/time/Duration.java)
> Seconds + nanoseconds approachwithout negative flag. Negative durations are represented by a
> negative number of seconds while nanoseconds are guarantied between >= 0 and < NANOS_PER
> SECOND
>
> * Rust (https://doc.rust-lang.org/src/core/time.rs.html)
> Seconds + nanoseconds approach without negative flag. Both numbers are unsigned - so no support
> of negative durations.
For additional point of reference, in Swift, Duration is internally represented as a 128-bit integer
count of attoseconds (!), with accessors that return an Int128 attoseconds, or a (seconds,
attoseconds) Int64 pair. With the pair accessor, negative durations are represented by both the
seconds and attoseconds components being negative when nonzero. There are static helpers that
provide initialization in terms of int and float seconds/milliseconds/microseconds/nanoseconds, but
there is no float output; if one wants a float, one gets one of the int versions and does the
relevant conversion.
Personally, I'm on the fence about negative durations, since it's an unphysical concept,
but allowing negative values makes calculations easier. For example, by allowing (allowedDuration -
actualDuration) where allowed < actual. The relevant Swift Evolution proposal says nothing
explicitly about negative values, except through implication they're allowed since durations
can be added and subtracted (and multiplied and divided).
Given that prior art, I would propose that the Duration class be changed to store 128-bit attosecond
counts as well. Although no specific rationale is given in the Swift Evolution proposal, I expect
that it's because modern cpus are capable of sub-nanosecond precision, which means
nanosecond-precision is _already_ lossy today, and attoseconds are such a hilariously small unit of
time that they allow for quite ample future-proofing. (1 attosecond == 10^-18 s; if I did the math
right, a signed 128-bit attosecond count gives a time range of ±5.39 trillion years, over 750x the
age of the universe.)
Even if we deem attoseconds are too small and go for some unit between nanoseconds and attoseconds,
it should still be possible to represent negative values.
-John