Re: [PHP-DEV] [RFC] Duration class

[email protected] ("Marc B.")
Newsgroups php.internals
Message-ID <[email protected]>
On 24.06.26 13:03, Tim Düsterhus wrote:
> Hi
>
> Am 2026-06-23 08:19, schrieb [email protected]:
>> What you feel unintuitive is just addition of two numbers in 
>> different units "$seconds + $nanoseconds * 1_000_000_000", which for 
>> me feels very natural.
>
> No, what I feel is unintuitive is that the magnitude of the Duration 
> will because *smaller* when the magnitude of the nanosecond value 
> becomes *larger*. You could phrase it as “the representation of a 
> single value as two values with different signs is unintuitive”. The 
> different units are not the issue, the different sign is.
>
>> With the negative flag it's more complicated "($negative ? -1 : 1) * 
>> $seconds + $nanoseconds * 1_000_000_000" to obtain the correct meaning.
>
> This example snippet is incorrect. The correct version would be: 
> `($negative ? -1 : 1) * ($seconds + $nanoseconds * 1_000_000_000)` 
> (with parentheses). In fact this snippet includes the snippet you 
> consider to be “very natural”, it just makes the application of the 
> sign explicit and effectively applies it to both components (instead 
> of one component like Java does), which means that the magnitude of 
> `$seconds` is a correct lower bound for the magnitude of the entire 
> Duration.
>
> To give a specific example in Java 
> (https://www.programiz.com/online-compiler/1Iilpy8ncbwRS):
>
>     import java.time.Duration;
>
>     class Main {
>         public static void main(String[] args) {
>             Duration d = Duration.parse("PT-59.5S");
>             System.out.println(d.getSeconds());
>             System.out.println(d);
>         }
>     }
>
> This will print:
>
>     -60
>     PT-59.5S
>
> Just by looking at the “seconds” component it looks like the Duration 
> is at least 1 minute long. But it isn't, because if the second 
> component is negative, the larger the value of the nanosecond 
> component is, the shorter the duration will be.

An alternative would be to use the same sign for nanoseconds as for 
seconds (while 0 seconds is neither positive or negative)

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.

>
>> In the RFC you say
>>> Negative durations are represented by an explicit $negative 
>>> property. This makes it easy to deal with absolute values by just 
>>> ignoring the value of $negative.
>>
>> That's just not true - you can't simply ignore the sign you have to 
>> deal with it no matter what. it's changing your calculations, it'g 
>> getting rejected on passing it to other functions.
>> On the same time the current API makes it harder to deal with 
>> negative durations as they can not be constructed directly and are 
>> not allowed as operator arguments.
>
> The statement is correct, if you are interested in absolute values, 
> you have the magnitude right there and can ignore the `$negative` 
> flag. But to make it even easier, we added the `->absolute()` method 
> that just clears the sign. Simply replacing seconds by abs(seconds) in 
> Java's representation would *not* be correct. In fact the OpenJDK 
> implementation defers to a BigDecimal calculation to flip the sign, 
> which is not an option for PHP, because the minimal PHP build doesn't 
> include either GMP or bcmath.

"... if you are interested in absolute values, you have the magnitude 
right there and can ignore the `$negative` flag."

No I can't
* adding two durations does NOT guaranties a value greater than the two
* passing a negative duration as timeout might throw
* ...


Thanks for adding `absolute()` - that's very helpful


>
>> Java does not have property hooks (as far as I know) but PHP now has.
>> That's very powerful and makes it possible to hide implementation 
>> details without exposing everything as getters.
>>
>> $duration->seconds // 0-59
>> $duration->totalSeconds
>> $duration->nanoseconds // 0 - 999_999_999
>> $duration->totalNanoseconds
>> $duration->milliseconds // 0 - 999
>> $duration->totalMilliseconds
>> // maybe later
>> $duration->picoseconds // 0 - 999_999_999_999
>> $duration->totalPicosecond
>>
>> As a user you don't need to care that much of the internal 
>> representation.
>
> The currently proposed properties are intended to be used by the user 
> directly. That's why they are public. 

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.

>
> Best regards
> Tim Düsterhus
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.