You are currently viewing PHP DateTime : tout savoir pour manipuler les dates

PHP DateTime : tout savoir pour manipuler les dates

Dans cet article

  • La classe DateTime remplace avantageusement les fonctions procédurales date() et time() depuis PHP 5.2
  • Le constructeur accepte plus de 50 formats de chaînes reconnus nativement par le parser PHP
  • DateTimeImmutable est recommandé en production pour éviter les mutations accidentelles d’objets
  • Les fuseaux horaires se gèrent via DateTimeZone avec plus de 400 identifiants IANA disponibles
  • La méthode diff() retourne un objet DateInterval permettant des calculs précis entre deux dates
  • Le format ISO 8601 (c ou DATE_ATOM) reste le standard pour les échanges API et le stockage en base

En formation BTS SIO, la manipulation des dates revient dans quasiment tous les projets : gestion de réservations, calcul d’échéances, affichage conditionnel selon la période. Pourtant, je constate que beaucoup d’étudiants continuent d’utiliser les vieilles fonctions date() et mktime() sans connaître la puissance de la classe php datetime. Dans ce guide, je vous montre comment maîtriser DateTime et ses classes associées pour écrire du code propre, fiable et maintenable.

Comprendre la classe DateTime en PHP

Avant PHP 5.2, la gestion des dates reposait entièrement sur des fonctions procédurales comme date(), time(), strtotime() et mktime(). Ces fonctions fonctionnent toujours, mais elles présentent plusieurs limites : pas de typage fort, difficulté à gérer les fuseaux horaires, et code vite illisible quand les calculs se complexifient.

La classe DateTime apporte une approche orientée objet à la manipulation des dates. Elle encapsule une date, une heure et un fuseau horaire dans un seul objet. Vous pouvez ensuite formater, modifier, comparer et calculer des intervalles avec des méthodes claires et expressives.

Voici la hiérarchie des classes que vous devez connaître :

  • DateTimeInterface : l’interface commune (depuis PHP 5.5)
  • DateTime : la classe mutable qui implémente cette interface
  • DateTimeImmutable : la version immuable (depuis PHP 5.5)
  • DateTimeZone : la gestion des fuseaux horaires
  • DateInterval : la représentation d’un intervalle de temps
  • DatePeriod : l’itération sur une plage de dates

Cette architecture orientée objet s’intègre parfaitement dans un code structuré. Si vous travaillez déjà avec des énumérations PHP ou des structures conditionnelles comme le switch PHP, vous retrouverez la même logique de typage strict et de lisibilité.

La classe DateTime encapsule date, heure et fuseau horaire dans un seul objet PHP
La classe DateTime encapsule date, heure et fuseau horaire dans un seul objet PHP

Créer un objet DateTime : constructeur et méthodes statiques

Le php datetime constructor accepte une chaîne de date en premier paramètre et un objet DateTimeZone optionnel en second. Le parser de PHP reconnaît nativement des dizaines de formats.

Instanciation avec le constructeur

<?php
// Date et heure courantes
$now = new DateTime();

// À partir d'une chaîne
$date1 = new DateTime('2026-06-26');
$date2 = new DateTime('26 June 2026');
$date3 = new DateTime('next Monday');
$date4 = new DateTime('+3 days');

// Avec fuseau horaire explicite
$paris = new DateTime('now', new DateTimeZone('Europe/Paris'));

Si la chaîne passée est invalide, PHP lève une Exception. Je vous recommande donc de toujours encapsuler la création dans un bloc try/catch lorsque la valeur provient d’une saisie utilisateur.

Création avec createFromFormat()

Quand le format de la date d’entrée est connu (formulaire, import CSV, API externe), utilisez la méthode statique createFromFormat(). Elle est plus stricte et plus fiable que le constructeur :

<?php
// Format français jj/mm/aaaa
$date = DateTime::createFromFormat('d/m/Y', '26/06/2026');

// Format américain mm-dd-yyyy
$date = DateTime::createFromFormat('m-d-Y', '06-26-2026');

// Timestamp Unix
$date = DateTime::createFromFormat('U', '1782662400');

// Vérifier que le parsing a réussi
if ($date === false) {
    $errors = DateTime::getLastErrors();
    // Gérer l'erreur
}

Cette méthode retourne false en cas d’échec au lieu de lever une exception. C’est un piège classique : pensez toujours à vérifier le retour. Vous pouvez consulter les erreurs détaillées via DateTime::getLastErrors().

Autres méthodes de création

<?php
// Depuis un timestamp Unix
$date = (new DateTime())->setTimestamp(1782662400);

// Depuis un objet DateTimeImmutable
$mutable = DateTime::createFromImmutable($immutableDate);

// Depuis une interface (PHP 8.0+)
$immutable = DateTimeImmutable::createFromInterface($anyDateTimeObject);

Formater une date avec DateTime::format()

La méthode format() utilise exactement les mêmes caractères de formatage que la fonction date(). Voici les php datetime format les plus utilisés :

Caractère Description Exemple
Y Année sur 4 chiffres 2026
m Mois avec zéro initial 06
d Jour avec zéro initial 26
H Heure format 24h 14
i Minutes avec zéro initial 35
s Secondes avec zéro initial 09
l Jour de la semaine (texte complet) Friday
D Jour abrégé Fri
F Mois (texte complet) June
N Jour ISO de la semaine (1=lundi) 5
U Timestamp Unix 1782662400
c Format ISO 8601 2026-06-26T14:35:09+02:00

<?php
$date = new DateTime('2026-06-26 14:35:09');

echo $date->format('d/m/Y');          // 26/06/2026
echo $date->format('H:i:s');          // 14:35:09
echo $date->format('l d F Y');        // Friday 26 June 2026
echo $date->format('Y-m-d\TH:i:sP'); // 2026-06-26T14:35:09+02:00
echo $date->format(DATE_ATOM);        // Équivalent ISO 8601

Pour afficher les noms de mois et de jours en français, vous devez configurer la locale avec setlocale() et utiliser strftime(), ou mieux, l’extension IntlDateFormatter depuis PHP 8.1 (car strftime() est dépréciée). La documentation officielle d’IntlDateFormatter détaille tous les formats disponibles.

<?php
$formatter = new IntlDateFormatter(
    'fr_FR',
    IntlDateFormatter::FULL,
    IntlDateFormatter::SHORT,
    'Europe/Paris'
);
echo $formatter->format(new DateTime()); // vendredi 26 juin 2026 à 14:35

Modifier et calculer des dates avec modify() et diff()

Les php datetime functions de modification permettent d’ajouter ou soustraire du temps de manière expressive. C’est l’un des plus grands avantages de l’approche objet par rapport aux fonctions procédurales.

Modifier une date avec modify()

<?php
$date = new DateTime('2026-06-26');

$date->modify('+1 day');        // 2026-06-27
$date->modify('-2 months');     // 2026-04-27
$date->modify('+1 year');       // 2027-04-27
$date->modify('next monday');   // Prochain lundi
$date->modify('last day of this month'); // Dernier jour du mois

Modifier avec DateInterval et add()/sub()

Pour des modifications plus structurées, utilisez un objet DateInterval. La notation suit le standard ISO 8601 avec le préfixe P (period) :

<?php
$date = new DateTime('2026-06-26');

// Ajouter 1 an, 2 mois et 3 jours
$interval = new DateInterval('P1Y2M3D');
$date->add($interval);
echo $date->format('Y-m-d'); // 2027-08-29

// Soustraire 6 heures et 30 minutes
$interval = new DateInterval('PT6H30M');
$date->sub($interval);

Calculer la différence entre deux dates avec diff()

La méthode diff() retourne un objet DateInterval qui contient la différence exacte entre deux datetime php :

<?php
$debut = new DateTime('2026-01-15');
$fin = new DateTime('2026-06-26');

$diff = $debut->diff($fin);

echo $diff->days;    // 162 (nombre total de jours)
echo $diff->m;       // 5 (mois)
echo $diff->d;       // 11 (jours restants)
echo $diff->format('%m mois et %d jours'); // 5 mois et 11 jours

// Vérifier si la date est passée
if ($diff->invert === 1) {
    echo 'La date de fin est dans le passé';
}

Ce type de calcul est très courant en BTS SIO : calcul de durée de location, vérification d’échéance de paiement, comptage de jours ouvrés. C’est bien plus lisible que de jongler avec des timestamps en secondes.

La gestion des fuseaux horaires est essentielle pour les applications internationales
La gestion des fuseaux horaires est essentielle pour les applications internationales

Gérer les fuseaux horaires avec DateTimeZone

La gestion des fuseaux horaires est souvent négligée dans les projets étudiants, mais elle devient critique dès que votre application a des utilisateurs dans plusieurs pays. La classe DateTimeZone encapsule cette logique.

<?php
// Créer avec un fuseau explicite
$paris = new DateTime('now', new DateTimeZone('Europe/Paris'));
$tokyo = new DateTime('now', new DateTimeZone('Asia/Tokyo'));
$newYork = new DateTime('now', new DateTimeZone('America/New_York'));

echo $paris->format('H:i');   // 14:35
echo $tokyo->format('H:i');   // 21:35
echo $newYork->format('H:i'); // 08:35

// Convertir un fuseau vers un autre
$date = new DateTime('2026-06-26 14:00:00', new DateTimeZone('Europe/Paris'));
$date->setTimezone(new DateTimeZone('UTC'));
echo $date->format('H:i'); // 12:00 (UTC = Paris - 2h en été)

Pour les échanges avec une base de données ou une API REST, je recommande systématiquement de stocker en UTC et de convertir à l’affichage. Cette convention simplifie tous les calculs et évite les bugs liés aux changements d’heure été/hiver.

La liste complète des identifiants de fuseaux est disponible dans la documentation officielle PHP sur les fuseaux horaires. PHP supporte plus de 400 identifiants basés sur la base de données IANA.

Vous pouvez configurer le fuseau par défaut dans php.ini ou directement dans votre code :

<?php
// Dans php.ini
// date.timezone = "Europe/Paris"

// Ou dans le code
date_default_timezone_set('Europe/Paris');

DateTimeImmutable vs DateTime : lequel choisir ?

C’est l’un des points les plus importants de ce guide. La classe DateTime est mutable : quand vous appelez modify(), add() ou setTimezone(), l’objet original est modifié. Ce comportement peut provoquer des bugs subtils :

<?php
// ⚠️ Bug classique avec DateTime mutable
$dateDepart = new DateTime('2026-06-26');
$dateArrivee = $dateDepart; // Pas une copie, c'est une référence !
$dateArrivee->modify('+7 days');

echo $dateDepart->format('Y-m-d');  // 2026-07-03 ← Surprise !
echo $dateArrivee->format('Y-m-d'); // 2026-07-03

Avec DateTimeImmutable, chaque modification retourne un nouvel objet sans toucher l’original :

<?php
// ✅ Comportement sûr avec DateTimeImmutable
$dateDepart = new DateTimeImmutable('2026-06-26');
$dateArrivee = $dateDepart->modify('+7 days');

echo $dateDepart->format('Y-m-d');  // 2026-06-26 ✅ Inchangé
echo $dateArrivee->format('Y-m-d'); // 2026-07-03 ✅ Nouvelle instance

En pratique, je conseille toujours d’utiliser DateTimeImmutable sauf cas exceptionnel. Les frameworks modernes comme Symfony l’adoptent par défaut. Si vous travaillez avec des enums PHP, vous retrouvez la même philosophie : préférer les structures qui limitent les effets de bord.

Les deux classes implémentent DateTimeInterface. Typez vos paramètres de fonctions avec cette interface pour accepter les deux :

<?php
function estWeekend(DateTimeInterface $date): bool
{
    return in_array((int) $date->format('N'), [6, 7], true);
}

Convertir entre DateTime et timestamp Unix

Le php datetime to timestamp est une opération courante, notamment pour interagir avec des systèmes hérités, des cookies ou des tokens JWT.

DateTime vers timestamp

<?php
$date = new DateTime('2026-06-26 14:00:00', new DateTimeZone('Europe/Paris'));

// Méthode objet
$timestamp = $date->getTimestamp();
echo $timestamp; // 1782658800

// Via format()
$timestamp = (int) $date->format('U');

Timestamp vers DateTime

<?php
// Méthode 1 : constructeur avec @
$date = new DateTime('@1782658800');
echo $date->format('Y-m-d H:i:s'); // 2026-06-26 12:00:00 (UTC !)

// Méthode 2 : setTimestamp()
$date = new DateTime();
$date->setTimestamp(1782658800);

// Méthode 3 : createFromFormat()
$date = DateTime::createFromFormat('U', '1782658800');

Attention : quand vous créez un DateTime avec @timestamp, le fuseau est toujours UTC. Pensez à appeler setTimezone() si vous avez besoin d’un fuseau local. Cette subtilité provoque beaucoup de bugs en production.

Pour manipuler les valeurs retournées par ces conversions, notamment extraire des portions de chaînes, la fonction PHP substr reste un outil complémentaire utile.

Comparer et trier des dates en PHP

Les php datetime objects supportent nativement les opérateurs de comparaison, ce qui rend le code très lisible :

<?php
$aujourdhui = new DateTime();
$echeance = new DateTime('2026-12-31');
$passe = new DateTime('2025-01-01');

// Comparaisons directes
var_dump($aujourdhui < $echeance);  // true
var_dump($aujourdhui > $passe);     // true
var_dump($aujourdhui == $echeance); // false

// Attention : == compare date ET heure, pas l'identité objet
$a = new DateTime('2026-06-26 00:00:00');
$b = new DateTime('2026-06-26 00:00:00');
var_dump($a == $b);  // true
var_dump($a === $b); // false (objets différents)

Trier un tableau de dates

<?php
$dates = [
    new DateTime('2026-03-15'),
    new DateTime('2026-01-01'),
    new DateTime('2026-12-25'),
    new DateTime('2026-06-26'),
];

usort($dates, function (DateTime $a, DateTime $b): int {
    return $a <=> $b; // Opérateur spaceship
});

foreach ($dates as $d) {
    echo $d->format('Y-m-d') . "\n";
}
// 2026-01-01
// 2026-03-15
// 2026-06-26
// 2026-12-25

L’opérateur spaceship (<=>) fonctionne parfaitement avec les objets DateTime. Si vous gérez des résultats triés côté base de données, pensez aussi au SQL ORDER BY avec plusieurs colonnes pour optimiser vos requêtes en amont.

Itérer sur une plage de dates avec DatePeriod

<?php
$debut = new DateTime('2026-06-01');
$fin = new DateTime('2026-06-30');
$intervalle = new DateInterval('P1D'); // Chaque jour

$periode = new DatePeriod($debut, $intervalle, $fin);

foreach ($periode as $jour) {
    echo $jour->format('Y-m-d l') . "\n";
}

DatePeriod est idéal pour générer des calendriers, des plannings ou des rapports jour par jour. Notez que la date de fin est exclue par défaut ; ajoutez l’option DatePeriod::INCLUDE_END_DATE en PHP 8.2+ pour l’inclure.

Appliquer les bonnes pratiques DateTime dès les premiers projets en BTS SIO
Appliquer les bonnes pratiques DateTime dès les premiers projets en BTS SIO

Bonnes pratiques et erreurs fréquentes

Après des années à corriger des copies et accompagner des projets en BTS SIO, voici les pièges que je vois le plus souvent avec datetime php.

Les 5 erreurs les plus courantes

  1. Oublier le fuseau horaire : sans configuration explicite, PHP utilise le fuseau du serveur. En hébergement mutualisé, c’est souvent UTC, ce qui décale toutes vos heures affichées.
  2. Confondre m et i dans format() : m correspond au mois, i aux minutes. J’ai vu cette erreur des dizaines de fois.
  3. Ne pas vérifier le retour de createFromFormat() : la méthode retourne false en cas d’erreur, pas une exception.
  4. Mutation involontaire d’un objet DateTime passé en paramètre. Utilisez DateTimeImmutable.
  5. Stocker des dates locales en base au lieu d’UTC, ce qui rend impossible toute conversion fiable.

Mes recommandations

  • Utilisez DateTimeImmutable par défaut, DateTime uniquement si vous avez une raison précise.
  • Typez vos paramètres avec DateTimeInterface pour accepter les deux variantes.
  • Stockez en UTC dans votre base de données, convertissez à l’affichage.
  • Préférez createFromFormat() au constructeur quand le format d’entrée est connu.
  • Utilisez les constantes prédéfinies (DATE_ATOM, DATE_ISO8601) plutôt que de réécrire les formats standards.
  • Validez toujours les dates issues des formulaires : une valeur comme 31/02/2026 ne lèvera pas toujours d’erreur si vous ne vérifiez pas avec checkdate().

Pour tester si une variable contient une valeur exploitable avant de tenter une conversion en date, la fonction PHP empty vous évitera des erreurs inutiles. De même, quand vous construisez des structures conditionnelles complexes, veillez à couvrir les cas limites comme les dates nulles ou les formats inattendus.

La documentation officielle de la classe DateTime reste la référence la plus complète et à jour. Je vous recommande de la consulter régulièrement, notamment la section sur les formats de date supportés par le parser PHP.

À retenir

  • Privilégiez DateTimeImmutable dans tous vos nouveaux projets pour éviter les mutations accidentelles
  • Utilisez createFromFormat() avec vérification du retour pour parser les dates utilisateur
  • Stockez systématiquement vos dates en UTC et convertissez à l’affichage avec setTimezone()
  • Typez vos fonctions avec DateTimeInterface pour rester flexible entre mutable et immutable
  • Vérifiez les dates de formulaire avec checkdate() avant tout traitement métier

Questions fréquentes


Comment créer un objet DateTime en PHP ?

Vous pouvez créer un objet DateTime avec new DateTime() pour la date courante, new DateTime('2026-06-26') pour une date spécifique, ou DateTime::createFromFormat('d/m/Y', '26/06/2026') quand le format d’entrée est connu. Le constructeur accepte des expressions relatives comme '+3 days' ou 'next Monday'.


Quelle est la différence entre date() et DateTime en PHP ?

La fonction date() est procédurale et retourne une chaîne formatée. La classe DateTime est orientée objet et retourne un objet que vous pouvez modifier, comparer et manipuler avec des méthodes dédiées. DateTime gère aussi nativement les fuseaux horaires et les calculs d’intervalles, ce qui serait bien plus complexe avec les fonctions procédurales.


Comment convertir un DateTime en timestamp Unix ?

Utilisez la méthode getTimestamp() sur votre objet DateTime. Par exemple : $timestamp = $date->getTimestamp();. Vous pouvez aussi utiliser (int) $date->format('U') pour le même résultat. Dans l’autre sens, créez un DateTime depuis un timestamp avec new DateTime('@1782658800').


Pourquoi utiliser DateTimeImmutable plutôt que DateTime ?

DateTimeImmutable empêche les mutations accidentelles. Avec DateTime, appeler modify() change l’objet original, ce qui peut provoquer des bugs difficiles à détecter quand plusieurs parties du code partagent la même référence. DateTimeImmutable retourne un nouvel objet à chaque modification, laissant l’original intact. C’est la pratique recommandée dans les frameworks modernes comme Symfony.


Comment formater une date en français avec PHP DateTime ?

La méthode format() retourne les noms en anglais. Pour obtenir des dates en français, utilisez IntlDateFormatter avec la locale 'fr_FR'. Exemple : $formatter = new IntlDateFormatter('fr_FR', IntlDateFormatter::LONG, IntlDateFormatter::NONE); echo $formatter->format($date);. L’ancienne fonction strftime() est dépréciée depuis PHP 8.1.


Comment calculer la différence entre deux dates en PHP ?

Utilisez la méthode diff(). Par exemple : $diff = $date1->diff($date2);. Le résultat est un objet DateInterval avec les propriétés y (années), m (mois), d (jours), h (heures) et days (nombre total de jours). Formatez le résultat avec $diff->format('%a jours').


Lucie Moreau
Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.

Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.