Re: [RFC] Duration class

From: Date: Tue, 07 Jul 2026 13:59:19 +0000
Subject: Re: [RFC] Duration class
References: 1 2 3 4 5 6 7 8 9 10 11 12 13  Groups: php.internals 
Request: Send a blank email to internals+get-131792@lists.php.net to get a copy of this message
Hi On 2026-07-04 11:32, Marc B. wrote:
On 7/3/26 22:45, Marc B. wrote:
An alternative would be to use the same sign for nanoseconds as for seconds (while 0 seconds is neither positive or negative)
Yes, this is effectively mentioned in the “Design Considerations” section of the RFC.
I think you missed my point and truncated my explanation example. 1.5s = 1 second + 500_000_000 nanoseconds -1.5s = -1 seconds + -500_000_000 nanoseconds -0.5s = 0 seconds + -500_000_000 nanoseconds No negative flag needed to be handled separately.
I understood the suggestion, and disagree with it for the reasons mentioned later in the email.
The use cases you listed there are all passing the Duration object somewhere else, which I do not consider to be a case of “if you are interested […]”. The quoted sentence if referring to situations where your code is the end user of the Duration object and extracts the contents from it for further processing. And in those situations a sign-magnitude representation makes processing easier, because you have a single authoritative source of the sign, not one in each component and because you can extract the magnitude right away, without needing to flip the sign of each component.
If you care about positive values only - use absolute()
Perhaps I should've better phrased it as “magnitude” instead of “positive values”. There are multiple situations where having the magnitude available straight away is useful. The simplest case would be printing the duration in some way, for example:
    printf(
        "%s%d.%09ds",
        $duration->negative ? "negative " : '',
        $duration->seconds,
        $duration->nanoseconds,
    );
Then converting it into the “Java representation” is also more easily done, because I don't need to deal with the sign on the nanoseconds:
    $duration = Duration::fromMilliseconds(1500)->negate();
    printf(
        "%ds %dns\n",
        ($duration->negative ? -1 : 1) * ($duration->seconds + $duration->negative),
        $duration->nanoseconds,
    );
If you want to know the sign of the duration - the is still the is negative property - but it's a getter and not a required to be stored flag.
It seems we are in agreement with regard to the usefulness of the ->negative property then. The internal representation does not need to match the userland API and instead can choose any representation it wishes. With the restrictions written in the RFC internal implementation could decide to store the entire duration as a single int64_t. Or it could store it as a C struct timespec.
This does not answer the meaning difference of seconds vs. nanoseconds - it's confusing naming that seconds is the total amount of seconds in this duration but nanoseconds is the number of fractions of a second.
A value-object, such as Duration, is uniquely described by the sum of its properties. And in this case, it's quite literally the sum of the $seconds and $nanoseconds.
You missed your own $negative flag
No, I did not. The context was the naming of the seconds and nanoseconds properties. Also, then last sentence was intended as a light-hearted pun, not as normative RFC text.
Am I get you right that you dislike property get hooks on value objects in general?
Yes.
I'm afraid I don't see how one would get the assumption that $seconds would redundantly be equal to ($nanoseconds / 1_000_000_000) or something like that when the object only has $seconds and $nanoseconds properties without also having $milliseconds, $minutes, or something else. The confusion would also be quickly cleared up just by looking at the object and seeing that the $nanoseconds value is always smaller than 1 billion. In my opinion renaming the $nanoseconds to $fractionalNanoseconds would greatly decrease the ergonomics of the class.
I more thought about renaming $seconds into $totalSeconds.
I believe that this similarly increased verbosity without increasing clarity: It's very obvious when Duration exceeds 1 minute in length that this is the total number of seconds, because the value exceeds 60. And below that the difference doesn't matter. Also it's eassy to see that the class doesn't have $minutes or $hours properties. Best regards Tim Düsterhus

« previous php.internals (#131792) next »