Re: [RFC] Duration class

From: Date: Mon, 22 Jun 2026 15:11:26 +0000
Subject: Re: [RFC] Duration class
References: 1 2 3 4 5 6 7  Groups: php.internals 
Request: Send a blank email to internals+get-131455@lists.php.net to get a copy of this message
On Mon, Jun 22, 2026 at 9:01 AM <marc@mabe.berlin> wrote: > Hi Tim, > > > On 21.6.2026 15:52 CEST Tim Düsterhus <tim@bastelstu.be> wrote: > > > > > > Hi > > > > On 6/20/26 17:50, ignace nyamagana butera wrote: > > > Also why are there some restrictions on the factor argument of > divideBy and > > > multiplyBy to only accept positive integers ? > > > At least that is what I understood when I quickly checked the proof of > > > concept. Since Duration are signed instances that restriction seems > strange > > > ? > > > > Enforcing positive values for multiplication and division means that > > flipping the sign of a Duration is a deliberate action and not just > > something that happens as part of another operation. > > > > See also the last paragraph in the “Design considerations” section. > > I don't agree on this part of the "Design considerations". > > The split between seconds and nanoseconds is a reasonable approach but the > negative flag is not. Especially that it's not just an implementation > detail. This makes the Duration class a very special thing from any other > "number of unit" that needs special care on using it. > > I have looked up the implementations of other Duration classes you > mentioned - Go, Java, Rust - none of them have such kind of negative flag.. > > * Go (https://pkg.go.dev/time#Duration) > Just int64 of nanoseconds - negative durations are a negative number > > * Java ( > > https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/java/time/Duration.javaPyùªÍ > …°Y�µ½3Ž > ) > Seconds + nanoseconds approachwithout negative flag. Negative durations > are represented by a negative number of seconds while nanoseconds are > guarantied between >= 0 and < NANOS_PER SECOND > > * Rust (https://doc.rust-lang.org/src/core/time.rs.html) > Seconds + nanoseconds approach without negative flag. Both numbers are > unsigned - so no support of negative durations. > > So either we follow Rust's approach by defining "Negative durations are > meaningless" then they should not be supported at all - Means no negative > flag and guarantied positive values. > Or we support negative durations but than it should not be special and > following "normal" math. If you need an absolute duration make sure it's > positive ... Adding a abs() / > absolute() method (like in Java). > > Currently it looks like you tried a mix of "negative durations are > meaningless" but on the same time you want to support negative durations > resulting wired middle ground. > > To define which way to go I think we need to be clear on what the use > cases are and how other use cases will be handled later on. So is that > class only for stop-watch & timeouts cases then maybe Rust's approach makes > more sense but if we want this class to be used more generically like "diff > in seconds of point in time X and Y with direction" a more general duration > make more sense. Looking at Java again - The Period class does not support > times - just calendar units. > > Another small note in the naming of $seconds and > $nanoseconds ... The > one is the total number, while the other one is the fraction of the unit. > If we later on want to add more helper like total number of x and more > fraction of different units we have ambiguity naming here. > -> I would rename $seconds into > $totalSeconds so maybe later on we can > add `$seconds { get => $totalSeconds % 60 } > > > Regards, > Marc > > > > > > Best regards > > Tim Düsterhus > Hi Tim and Marc, 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, ); Best regards, Ignace

« previous php.internals (#131455) next »