On Mon, Jun 22, 2026, at 12:25 PM, Tim Düsterhus wrote: > Hi > > Am 2026-06-22 17:11, schrieb ignace nyamagana butera: >> I concur with Marc remarks especially if we want to add a divmod like >> method this simple example shows the issue one would run into with the >> current constraints. >> >> $duration = Duration::fromHours(3)->negate(); >> >> $factor = Duration::fromHours(1); >> [$count, $remainder] = $duration->divmod($factor); >> // using BCMath implementation for the example ! >> //[-3, Duration::fromSeconds(0)] is returned in the tuple >> >> Duration::sum( >> $factor->multiplyBy($count), // with the current constraints this >> will throw >> $remainder, >> ); > > I would personally find [3, Duration::fromSeconds(0)] (i.e. ignoring the > sign) to be a reasonable reply to the question “how often can I fit this > duration into the other duration”. > > In fact the output of a `divmod()` would be very confusing when the > divisor doesn't divide the dividend, since the result of the modulo > operator is always positive (see also: > https://stackoverflow.com/a/13683709): > > $duration = Duration::fromMinutes(3 * 60 + 20)->negate(); // > negative 3:20 hours > $factor = Duration::fromMinutes(60); // 1 hour > > $duration->divmod($factor); > // [-4, Duration::fromMinutes(40)] = (-4 * 60 minutes) + 40 minutes > = negative 3:20 hours > > A `divrem()` (“remainder”) would be: > > $duration = Duration::fromMinutes(3 * 60 + 20)->negate(); // > negative 3:10 hours > $factor = Duration::fromMinutes(60); // 1 hour > > $duration->divrem($factor); > // [-3, Duration::fromMinutes(20)->negate()] = (-3 * 60 minutes) - > 20 minutes = negative 3:20 hours > > In my opinion, implementing "Duration divided by Duration" as a > remainder operation is the only reasonable choice here and “ignoring the > sign” to avoid the entire “modulo vs remainder” discussion would be > reasonable when the method is appropriately named. > > Staying with the IEEE-754 comparison for the sign-magnitude > representation, I could also imagine adding a “copysign” method matching > the `copysign()` function > (https://man7.org/linux/man-pages/man3/copysign.3.html). > > The example would then be: > > Duration::sum($factor->multiplyBy($count), > $remainder)->copysign($duration); > > If we feel that the “Duration divided by Duration” *should* be able to > return negative values, then lifting the `>= 0` restriction of > `multiplyBy()` would also easily be possible. > > Best regards > Tim Düsterhus
To be clear, I absolutely hate using a static method here. Even if we're just using methods and not operators, $dur3 = $dur1->add($dur2) is the way to go. --Larry Garfield
