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

Reply via email to