Un client basé à La Réunion me signalait que ses articles publiés à 14h s’affichaient comme publiés à 10h sur le site. Rien de cassé : WordPress stocke bien les dates en heure locale et en UTC dans deux colonnes distinctes, mais le thème utilisait la fonction native date() de PHP pour formater l’affichage, une fonction qui ignore complètement le fuseau horaire réglé dans les réglages de WordPress.
Ce genre de décalage, discret en apparence, provoque des désagréments bien réels : articles qui semblent publiés dans le futur, horodatages de commentaires incohérents, plannings d’événements décalés d’une ou plusieurs heures selon la saison.
Ce que WordPress stocke réellement
Chaque article possède deux champs de date en base : post_date, exprimé dans le fuseau horaire réglé sur le site (Réglages → Général), et post_date_gmt, toujours en UTC. Le réglage du fuseau se fait dans l’option timezone_string (par exemple Indian/Reunion) ou, à défaut, dans gmt_offset pour un simple décalage horaire.
Pourquoi date() pose problème
La fonction native date() de PHP utilise le fuseau horaire par défaut du serveur, défini par date_default_timezone_set() ou la configuration php.ini, sans jamais consulter les réglages de WordPress. Sur un serveur configuré en UTC hébergeant un site réglé sur l’heure de la Réunion (UTC+4), l’écart de quatre heures apparaît immanquablement.

// À éviter dans un thème WordPress
echo date( 'd/m/Y H:i', strtotime( get_the_date() ) );
// Résultat : décalage possible selon le fuseau du serveur
wp_date : la bonne fonction pour l’affichage
Introduite en WordPress 5.3, la fonction wp_date() respecte le fuseau horaire réglé dans WordPress et gère correctement l’internationalisation des noms de mois et de jours, contrairement à date_i18n() qui reste disponible mais moins complète sur la gestion des fuseaux.
echo wp_date( 'd/m/Y à H\hi', get_post_timestamp( get_the_ID() ) );
// Ou directement à partir d'un timestamp Unix
$timestamp = strtotime( get_post()->post_date_gmt . ' UTC' );
echo wp_date( 'd F Y', $timestamp );
current_time : pour les calculs côté serveur
Quand il s’agit non pas d’afficher une date mais de la comparer ou de l’enregistrer (par exemple pour savoir si un événement est passé), current_time() retourne l’heure actuelle dans le fuseau du site ou en UTC selon le second paramètre :
$maintenant_local = current_time( 'timestamp' ); // Déprécié en faveur du format ci-dessous
$maintenant_local = current_time( 'U' ); // Timestamp Unix en heure locale WordPress
$maintenant_gmt = current_time( 'U', true ); // Timestamp Unix en UTC
if ( $maintenant_gmt > strtotime( get_post()->post_date_gmt . ' UTC' ) ) {
// L'article est déjà publié
}
Le piège des changements d’heure
Un fuseau horaire réglé via gmt_offset (un simple nombre d’heures de décalage) ne suit pas automatiquement les changements d’heure été/hiver, contrairement à un réglage via timezone_string (un identifiant de zone comme Europe/Paris). Sur un site où l’option est restée sur un décalage fixe hérité d’une ancienne installation, deux fois par an, tous les horodatages se décalent d’une heure.
// Vérifier le réglage actuel en ligne de commande WP-CLI
wp option get timezone_string
wp option get gmt_offset
Si timezone_string est vide et que seul gmt_offset est renseigné, je recommande systématiquement de migrer vers un identifiant de zone complet dans Réglages → Général, en sélectionnant une ville plutôt qu’un simple décalage UTC.
Tableau de correspondance rapide
| Besoin | Fonction à utiliser |
|---|---|
| Afficher une date au visiteur | wp_date() |
| Comparer deux dates côté serveur | current_time( ‘U’ ) ou current_time( ‘U’, true ) |
| Date de publication brute stockée | get_post()->post_date / post_date_gmt |
Dès qu’un projet touche à des utilisateurs hors de métropole, je vérifie en premier le réglage du fuseau horaire : c’est la cause la plus fréquente de dates « fausses » qu’on me signale.
En résumé
La fonction native date() de PHP n’a pas sa place dans un thème ou une extension WordPress dès qu’il s’agit de dates issues de contenus. wp_date() pour l’affichage et current_time() pour les calculs suffisent à éliminer la quasi-totalité des décalages horaires signalés par les utilisateurs.