Re: [RFC] Duration class

From: Date: Wed, 01 Jul 2026 18:18:44 +0000
Subject: Re: [RFC] Duration class
References: 1 2 3 4 5 6 7 8 9  Groups: php.internals 
Request: Send a blank email to internals+get-131667@lists.php.net to get a copy of this message
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 Durations, 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

« previous php.internals (#131667) next »