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