PHP has no consistent way to express "this much time." Some functions take seconds as an int, others take milliseconds, and some split seconds and microseconds into two parameters. A few use a float, which can lose precision. This RFC from Tim Düsterhus and Derick Rethans adds a Time\Duration class that stores a length of time the way a stopwatch would, down to the nanosecond.
Why not DateInterval#
DateInterval can hold days and months, and those don't map to a fixed number of seconds. A month has anywhere from 28 to 31 days, and a day can be longer or shorter when clocks change for daylight saving time. A Duration only goes up to hours, so its length is always exact.
Show me#
Here is a trimmed version of the RFC's example:
use Time\Duration;
$oneSecond = Duration::fromSeconds(1);
$halfSecond = $oneSecond->divideBy(2);
$onePointFiveSeconds = $oneSecond->add($halfSecond);
$negativeHour = Duration::fromHours(1)->negate();
$baseDelay = Duration::fromMilliseconds(100);
$delay = $baseDelay->multiplyBy(2 ** 5);
You create a Duration with a named constructor for the unit you want: fromSeconds(), fromNanoseconds(), fromMicroseconds(), fromMilliseconds(), fromMinutes() or fromHours(). You can also parse an ISO 8601 duration string with fromIso8601DurationString().
How it works#
- The class is
final and readonly, and every method returns a new object.
- It has three properties:
$seconds, $nanoseconds and $negative.
- The math methods are
add(), sub(), multiplyBy(), divideBy(), negate() and absolute().
Duration::compare() returns -1, 0 or 1. Comparison operators like < also work, but arithmetic operators like + don't.
- Overflows throw a new
Time\TimeException.
- It can represent about 292 years.
The RFC doesn't change existing functions like sleep() to accept a Duration. The one exception is the new polling API, also planned for PHP 8.6, whose wait() method takes a ?Time\Duration $timeout instead of two numeric parameters.
The authors describe this as the first piece of a new date and time library for PHP.
What it means for existing code#
Nothing breaks, since everything lives in a new Time namespace. A GitHub search found only 7 projects with their own Time\Duration class, and two of those were polyfills aimed at the same problem.