veilletech.fr
28 août Feed du jour
#05 PHP Article

PHP 8.6 : Duration, enfin des durées précises

Une durée qui porte son unité, c'est un bug de moins.

PHP 8.6 ajoute Time\Duration, une classe finale et readonly pour représenter une durée à la nanoseconde près. Elle comble un trou laissé par DateInterval, taillé pour le calendrier et malhabile dès qu'il faut compter juste sur un délai de quelques millisecondes.

2 min de lecturevidéo 1:24
Partager
Sommaire4 sections
  1. Ce qui se passe
  2. Comment s'en servir
  3. Ce que ça change
  4. À retenir

Ce qui se passe

Jusqu'ici, un délai en PHP s'écrivait avec un entier nu. retryAfter(500) : secondes ou millisecondes ? Le type ne dit rien, et le lecteur devine. La RFC Duration class apporte à PHP 8.6 un type pour ce que la spécification nomme une durée « chronomètre » : le temps qu'on attend ou qu'on mesure, sans rapport avec une position dans le calendrier. Délai avant réessai, durée de vie d'un verrou, plafond d'une requête HTTP.

DateInterval ne convenait pas : bâti pour exprimer la distance entre deux dates en jours, en mois et en années, il devient approximatif dès qu'on compte finement. La nouvelle classe habite son propre espace de noms, Time\Duration, et descend jusqu'à la nanoseconde.

Comment s'en servir

Elle est final et readonly : pas de sous-classe, pas de mutation, chaque opération rend une instance neuve. On ne l'instancie pas avec new mais par fabriques :

PHP
use Time\Duration;

$timeout = Duration::fromMilliseconds(500);
$pause   = Duration::fromMinutes(5);
$iso     = Duration::fromIso8601DurationString('PT1H30M');

Les autres points d'entrée sont fromSeconds(int $seconds, int $nanoseconds = 0), fromMicroseconds(), fromNanoseconds() et fromHours(). L'objet expose ensuite trois champs qu'on peut lire sans pouvoir les écrire : $seconds, $nanoseconds — plafonnées à 999 999 999 — et $negative. Porter le signe dans un booléen à part plutôt que dans les secondes est un choix assumé : la valeur absolue se calcule alors sans effort.

L'arithmétique ne passe pas par les opérateurs, mais par des méthodes :

PHP
$base = Duration::fromMilliseconds(100);
$attente = $base->multiplyBy(2 ** $tentative);   // backoff exponentiel
$total   = $attente->add(Duration::fromSeconds(2));

Avec sub(), divideBy(), negate() et absolute() pour compléter. Deux détails à connaître : multiplication et division n'acceptent que des entiers, et le reste d'une division est tronqué, jamais arrondi.

La comparaison, elle, fonctionne avec <, > et == grâce à l'ordre de déclaration des propriétés internes ; une méthode statique compare() rend -1, 0 ou 1 pour un usort().

Toute opération hors domaine — nanosecondes invalides, diviseur nul, dépassement — lève Time\TimeException.

Ce que ça change

Le premier bénéficiaire est le mécanisme de scrutation introduit dans la même version, dont la méthode d'attente prend maintenant l'objet en argument :

PHP
$watchers = $context->wait(Duration::fromMilliseconds(500));

La RFC annonce par ailleurs une refonte plus vaste du traitement des dates et des heures, dont cette classe serait le point de départ. Sans attendre la suite, le bénéfice est immédiat partout où traînent des délais : l'unité quitte le nom de la variable pour entrer dans le type.

Source : [ShevArezo`Blog, PHP 8.6 : la nouvelle classe Duration pour manipuler des durées de temps](https://blog.shevarezo.fr/post/2026/08/26/php-8-6-nouvelle-classe-duration-manipuler-durees-de-temps) (en français) · RFC