Re: [PHP-DEV] [RFC] Duration class
[email protected] (Tim Düsterhus) Tue, 07 Jul 2026 15:59:19 +0200
| Newsgroups | php.internals |
|---|---|
| Message-ID | <[email protected]> |
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