Un format de date codé en dur ailleurs dans un thème ne se corrige jamais tout seul, même quand tout le reste du texte change de langue correctement. C’est exactement ce qui s’est produit sur un thème qui affichait la date de publication d’un article dans un format américain (06/20/2024) alors que la page entière — titre, menu, pied de page — s’affichait parfaitement en français après un appel à switch_to_locale( 'fr_FR' ) dans une routine de génération de contenu multilingue programmatique.
Le réflexe naturel a été de suspecter switch_to_locale() lui-même, en se demandant s’il fonctionnait vraiment. Ce n’était pas le problème : la fonction faisait exactement ce qu’elle promet. Le bug se trouvait ailleurs, dans une hypothèse implicite du code du thème.
Ce que switch_to_locale() change réellement
switch_to_locale() recharge les fichiers de traduction du domaine de texte courant pour la locale demandée, et met à jour l’objet global $wp_locale avec les données spécifiques à cette langue (noms de mois, jours de la semaine, séparateur décimal). Elle ne touche en revanche à aucune chaîne déjà générée avant son appel, ni à aucun format codé en dur dans le thème.
switch_to_locale( 'fr_FR' );
$titre = __( 'Publié le', 'mon-theme' ); // Correctement traduit
$date = date( 'm/d/Y', strtotime( $post->post_date ) ); // Toujours au format US
restore_previous_locale();
Le format de date, ici, est produit par la fonction PHP native date(), qui ne connaît rien de la locale WordPress. Elle applique le format littéral qu’on lui donne (m/d/Y), sans jamais consulter $wp_locale ni la locale active. Voilà l’origine exacte du décalage.

Le bon réflexe : date_i18n() plutôt que date()
WordPress fournit une fonction dédiée, date_i18n(), qui applique bien le format demandé mais en traduisant les éléments variables (noms de mois, jours) selon la locale active au moment de l’appel :
switch_to_locale( 'fr_FR' );
$date = date_i18n( get_option( 'date_format' ), strtotime( $post->post_date ) );
restore_previous_locale();
Avec cette version, un article publié en fr_FR affiche bien « 20 juin 2024 » au lieu de « June 20, 2024 », parce que date_i18n() consulte les tableaux de $wp_locale pour traduire les noms de mois — exactement ce que date() ne fait jamais.
Le rôle sous-estimé de get_option( ‘date_format’ )
Un piège annexe se présente souvent ici : le format de date stocké dans l’option date_format est unique par site, pas par langue. Rien n’empêche un format américain m/d/Y configuré comme réglage général, même sur un site principalement francophone. Si le projet a besoin d’un format différent par langue (ce qui est fréquent : jour/mois/année en français, mois/jour/année en anglais américain), il faut résoudre ce format manuellement selon la locale active, plutôt que de se fier à l’option globale du site.
function get_date_format_for_locale( $locale ) {
$formats = [
'fr_FR' => 'j F Y',
'en_US' => 'F j, Y',
'de_DE' => 'd.m.Y',
];
return $formats[ $locale ] ?? get_option( 'date_format' );
}
WP_Locale : ce qu’il expose, ce qu’il n’impose pas
L’objet global $wp_locale, une instance de la classe WP_Locale, contient les tableaux de traduction des noms de mois et de jours, le séparateur décimal, le séparateur de milliers, ainsi que la direction d’écriture (LTR ou RTL). Il ne décide en revanche jamais tout seul du format d’affichage d’une date ou d’un nombre — c’est au code appelant de consulter ces données, via des fonctions comme date_i18n() ou number_format_i18n(), plutôt que via les fonctions PHP natives.
$wp_locale->month: tableau des noms de mois traduits$wp_locale->weekday: tableau des noms de jours traduits$wp_locale->number_format: séparateurs décimal et de milliers par locale
Prévention : bannir date() et number_format() du code de rendu
La règle la plus simple à appliquer sur un projet multilingue consiste à interdire, via une revue de code systématique, tout appel direct à date() ou number_format() dans les gabarits de rendu, au profit de date_i18n() et number_format_i18n(). Cette règle, une fois documentée dans les conventions de l’équipe, évite que ce genre de bug ne réapparaisse à chaque nouvelle fonctionnalité.
Une fonction de locale WordPress ne rattrape jamais un format codé en dur ailleurs : elle change le contexte, pas le code qui l’ignore.
En résumé
Le piège de switch_to_locale() ne vient pas de la fonction elle-même, mais de tout le code qui continue d’utiliser des fonctions PHP natives insensibles à la locale WordPress. date_i18n(), number_format_i18n() et une consultation explicite de $wp_locale permettent d’aligner réellement l’affichage sur la langue active, là où un simple changement de locale ne suffit jamais à lui seul.