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

[email protected] ("Larry Garfield")
Newsgroups php.internals
Message-ID <[email protected]>
On Wed, Jul 1, 2026, at 12:22 PM, Tim Düsterhus wrote:
> Hi
>
> Am 2026-06-23 15:04, schrieb Tim Düsterhus:
>> Both Derick and I were receptive to the `Duration::sum()` suggestion.
>> 
>> One big benefit I am personally seeing is that it would allow to rename 
>> the `negate()`, `multiplyBy()`, and `divideBy()` methods to use “past 
>> tense” (is that the correct term?) to indicate that they return a copy, 
>> without requiring awkward naming like `added()`. `->sub()` is also 
>> technically redundant due to the existence of negative Durations, thus 
>> there is no need for a mirrored pair like multiplication / division, 
>> since the information can be encoded in the Duration object itself.
>> 
>> To avoid readers making assumptions, can you spell out your arguments 
>> against replacing `->add()` and `->sub()` by a unified `::sum()` 
>> method?
>
> To close this out ourselves: While having a static `sum()` method works 
> for `Duration`s, since the Duration with addition forms an abelian 
> group, this doesn't work for the other future-scope classes where 
> addition doesn't form an (abelian) group. More specifically: Adding two 
> Instants together is not a meaningful operation. Adding a Duration to an 
> Instant however is. Using something like:
>
>      $epoch = Instant::fromUnixtime(0);
>      $onePointFiveHoursLater = Instant::sum($epoch, 
> Duration::fromMinutes(30), Duration::fromHours(1));
>
> would be very weird. Instead `->add()` is the obvious operation here:
>
>      $epoch = Instant::fromUnixtime(0);
>      $onePointFiveHoursLater = $epoch
>          ->add(Duration::fromMinutes(30))
>          ->add(Duration::fromHours(1));
>
> notably this would also work then:
>
>      $epoch = Instant::fromUnixtime(0);
>      $onePointFiveHoursLater = $epoch
>          ->add(
>              Duration::fromMinutes(30)
>                 ->add(Duration::fromHours(1)
>          );
>
> making the Instant + Duration -> Instant operation a “right group 
> action”.

How about that.  Forgetting to respond to this thread meant you gave a good response for me.  Thanks, Tim. :-)

> We will thus keep instance methods for “addition” and “subtraction”. If 
> someone has a suggestion regarding naming (particularly with regard to 
> negate() vs negated() and multiplyBy() and multipliedBy()), I'll be 
> happy to discuss that. Java uses plus, minus, multipliedBy, dividedBy 
> and negated. Golang is just using an integer (meaning you just use the 
> operators). Rust’s std::time::Duration uses add, sub, mul, div (with 
> saturating and checked variants), but also overloads operators. Rust’s 
> chrono::TimeDelta is similar to std::time::Duration, but doesn't have 
> the saturating variants. JavaScript’s Temporal uses add, sub, negated 
> and doesn't support multiplication and division.
>
> Please keep the `divide**By**()` (Duration / int -> Duration) vs 
> `divide**Into**()` (Duration / Duration -> (int, Duration)) suggestion 
> in mind when having opinions about the naming. See: 
> https://news-web.php.net/php.internals/131634

negated() would be consistent with the "ed means return new" pattern found in many languages, so I would strongly recommend following that pattern.

For the others, my inclination is to go short (add, sub) for easier typing and a more compact result, but that's not a make-or-break issue for me.

--Larry Garfield
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.