Afficher les dates en français

Nous allons définir la configuration locale grâce à la fonction PHP setlocale(), et ce en fonction de l’environnement : développement ou production.

1. Définition de la configuration locale

La fonction PHP setlocale() permet de modifier les informations de localisation de notre application. Elle prend en paramètre la catégorie de fonctions affectée, et le nom de la locale.

Plus d’information sur la fonction setlocale() sur le site officiel PHP

Le nom de la locale dépend du système d’exploitation, c’est pourquoi nous allons faire une double configuration automatique selon l’environnement du site. Nous allons définir la configuration locale dans le fichier {app}/config/bootstrap.php, et faire un test sur l’adresse IP à l’origine de la requête comme expliqué dans un autre sujet.

1
2
3
4
5
6
7
8
9
10
11
12
13
// {app}/config/bootstrap.php
if(env('REMOTE_ADDR') == '127.0.0.1')
{
  // Local (Windows dans notre cas)
  $locale = 'french';
}
else
{
  // En ligne
  $locale = 'fr_FR';
}
// Définition de la locale pour toutes les fonctions php relatives à la de gestion du temps :
setlocale(LC_TIME, $locale);

2. Affichage d’une date

Voyons l’effet de notre configuration : imaginons un blog avec des articles dont nous voulons afficher la date de création. Dans la Vue de l’action view :

1
2
3
4
5
6
7
8
// {app}/views/articles/view.ctp
 
// Le titre de l'article :
e($article['Article']['titre'].'<br />');
 
// Date de création :
$timestamp = strtotime($article['Article']['created']);
e("Créé le ".strftime("%d %B %Y à %H:%M", $timestamp));

Notre vue affiche bien :

Mon premier article Créé le 12 février 2008 à 19h51

3. Les champs date dans un formulaire

Autre effet de notre configuration : lorsque nous créons un formulaire avec un champ date (sous forme de 3 listes déroulantes pour le jour, le mois et l’année), nous aimerions que les mois de l’année soient affichés en français et que les champs soient présentés dans l’ordre « jour – mois – année » et non pas « mois – jour – année » comme en anglais.

Dans la Vue de l’action edit :

1
2
3
4
// {app}/views/articles/edit.ctp
e($form->create('Article', array('action' => 'edit')));
e($form->input('created', array('dateFormat' => 'DMY', 'label' => 'Date de création')));
e($form->end('Valider'));

Nous avons précisé l’ordre dans lequel nous souhaitions voir apparaître les 3 listes déroulantes grâce à l’option dateFormat, et grâce à notre définition de la locale, la liste déroulante du milieu, celle des mois de l’année, montre bien les mois en français.

Pierre-Emmanuel Fringant

Articles connexes

Commentaires

Bonjour,

Merci pour ce tutoriel mais comment mettre en francais la fonction du helper time : timeAgoInWords ? Merci

La méthode timeAgoInWords retourne une chaîne directement construite en anglais dans la méthode, la seule solution est de créer un nouveau helper et de recopier la fonction en changeant son comportement.

On peut aussi ajouter derrière la locale le codage des caractères, celui du système est parfois différent de celui de l’application. Par exemple pour forcer latin1 sur un système en utf-8, on fera setlocale(‘fr_FR.ISO8859-1′);

Il existe également d’autres constantes que LC_TIME pour les nombres, les comparaisons de chaînes etc

Pour plus d’infos (surtout dans les commentaires) : http://fr.php.net/manual/fr/function.setlocale.php

Salut,

Et encore bravo pour ton blog, qui est de loin le plus utile et le plus clair de la communauté française du Gâteau !

La possibilité de définir la locale dans Bootstrap est récente je crois, car il y a encore quelques semaines, il m’avait fallu créer un Helper LocaleTime pour gérer l’affichage des dates dans d’autres formats que l’anglo-américain…

C’est donc une bonne nouvelle et je vais de ce pas jeter mon helper dans la corbeille !

Avairet

Merci pour tes encouragements !

Me revoilà !

J’ai repris mon helper LocalTime pour voir comment j’avais fait et je pense que l’on peut faire plus rapide et non dépendant de la machine :

$locale = ‘frFR’; if (strpos(« Win », $SERVER["HTTPUSERAGENT"])) { $locale = ‘fra’; } setlocale(LC_TIME, $locale);

Je me corrige, ce n’est pas dépendant de l’IP, mais bien de l’OS…

Salut,

Je reviens sur ce sujet, car j’ai testé ta méthode et dans mon formulaire, le nom des mois est toujours en anglais… Voici ce que j’ai mis dans mon fichier bootstrap.php :

$locale = ‘frFR’; if (isset($SERVER['HTTPUSERAGENT']) && strpos(« Win », $SERVER['HTTPUSERAGENT'])) { $locale = ‘french’; } setlocale(LCTIME, $locale);

Tu t’étais pourtant corrigé toi-même dans un commentaire précédent : la locale ne dépend pas du client. $SERVER[’HTTPUSERAGENT’] te donne le nom du navigateur d’un visiteur, alors que la locale doit être définie en fonction de l’environnement du serveur. Je reconnais que le nom $SERVER pour récupérer des infos sur le visiteur est très mal choisi et prête à confusion, la preuve !

Holà, mais pourtant, j’ai utilisé la même chose dans mon Helper « localtime » que j’avais bidouillé il y a quelques semaines pour obtenir le même résultat que toi… et je n’avais aucun souci !

Dans nos exemples, ce qui compte, c’est « setlocale(LC_TIME, $locale) », non ?

Donc apparemment, ce qui bloque, c’est que je suis sous Windaube et que ma locale « french » n’est pas prise en compte du fait de l’utilisation de $_SERVER ??

Mais pourtant, le fichier « bootstrap.php » est appelé dès que je fait une requête depuis mon navigateur…

Bon OK, je viens d’ajouter :

« if (env(‘REMOTE_ADDR’) == ’127.0.0.1′ ||  » au début de mon test

et cela fonctionne, par contre, j’ai un souci d’accents dans « février », pour mon helper Localtime, j’avais donc ajouter :

$date_format = strftime($format,$date);

$dateformat = iconv(‘ISO-8859-1′, ‘UTF-8′, $dateformat);

Mais ces ajouts ne peuvent pas se faire dans le « bootstrap » et ni dans le « form->input() »…

Donc si on utilise de l’utf-8, on ne peut pas utiliser tel quel ton exemple ? On doit forcément réécrire la méthode input du helper Form ou bien créer comme moi un autre helper…

Relis le commentaire de Matthieu (n°3) : tu peux ajouter le codage des caractères après la locale : setlocale(’frFR.ISO8859-1′); ou setlocale(’frFR.UTF-8′);

Oups, oui désolé, j’avais oublié le commentaire de Matthieu…

Mais je viens de tester et cela ne marche pas chez moi ?!

Que je fasse : setlocale(LCTIME, ‘frFR.UTF-8′) ou setlocale(LCTIME, ‘frFR.ISO-8859-1′) ou setlocale(LCTIME, ‘french.UTF-8′)

En fait, dès que j’ajoute quelque chose derrière la locale, il me remet les noms des mois en anglais dans mes formulaires. D’après la doc PHP et les commentaires des users, il semble que l’ajout du Charset après la locale ne fonctionne pas sous Windows.

Parfois, l’affichage des noms de mois repasse en Anglais à la volée, c’est comme si bootstrap.php n’était pas toujours lu… J’ai essayé de faire mon set_locale à différents endroits, sans succès. Un simple F5 (refresh) de la page en cours remet les noms en français, mais c’est tout de même pas terrible pour le client… As-tu constaté ce genre de choses ?

Pour ma part, jamais. Le bootstrap reste le meilleur endroit pour définir la locale.

Alors d’où peut provenir ce problème ? Je précise que cela se produit essentiellement dans des champs date produit par le helper Form.

C’est très aléatoire et fort désagréable à l’usage…

Tu as raison Aurélien, je viens tout juste d’avoir le même bug. Sur une même page, j’affiche un ensemble de plusieurs listes déroulantes contenant chacune les 12 mois de l’année en toutes lettres : parfois tout est bien français, parfois l’une des listes est en anglais, parfois plusieurs, parfois toutes en anglais… C’est très curieux et paraît totalement aléatoire… J’aimerai ouvrir un ticket sur le trac, mais je ne pense pas qu’il soit pris en compte puisque c’est un bug aléatoire qui peut difficilement être reproduit. Une part de gâteau à qui trouvera la parade.

Et oui, j’ai encore et toujours ce même problème ! Et je suis content que tu me soutiennes ;o) Je pense au cache, aux includes de bootstrap qui ne se ferait pas comme il faut, au navigateur… Mais tu devrais écrire un ticket quand même ! Pour ma part, afin que le client soit content, je pense que je vais me taper tous les select à la main avec une liste d’option françaises…

Avec toutes les modifs sur le Core de ces derniers jours, j’ai constaté une amélioration du phénomène, mais avcec la dernière révision, c’est encore pire : ils ont codé le nom des mois anglais en dur !

Du coup il faut utiliser le fichier de traduction « .po » pour les mettre en français… c’est pas très pratique et cela met à bas notre idée de la locale configurée dans Bootstrap.

Suite à un échange sur le Trac, j’ai la confirmation que le nom des mois est désormais coder en dur (via la syntaxe gettext) dans le helper Form, méthode __generateOptions(), et qu’il est donc nécessaire d’ajouter leur traduction à notre fichier .po !

Je trouve cela un peu fastidieux car il faut faire un extract des strings du core de Cake et les merger avec notre fichier default.po

Par contre, il semble que maintenant, il n’y ait plus d’affichage aléatoire entre l’anglais et le français.

Du coup, j’en viens à me demander si le « setlocale » dans Bootstrap est encore utile… d’autant que mon interlocuteur sur le Trac, « markstory », utilise comme argmuent de justification de ce changement, qu’il ne faut pas faire confiance aux « server settings » comme set_locale ?!

J’attends la sortie de la 1.2 stable, mais je pense effectivement migrer vers la solution des fichiers de traduction et ne plus m’appuyer sur le set locale.

Avec la version 1.2.0.7125-rc1, on peut passer un booléen ‘monthNames’ pour afficher les mois par leur nom (par défaut) ou en chiffres.

L’affichage des mois en chiffres règle le problème de la langue…

Exemple : $form->dateTime( 'date_publication', 'DMY', 'NONE', time(), array('monthNames' => false), false ));

Oui, à moins que les noms des mois soit une exigence du client !

La parade pour afficher les mois en français : extraire les chaînes du coeur pour les traduire : http://www.formation-cakephp.com/43/multilingue-quelques-astuces

C’est effectivement pratique de pouvoir traduire les mois.

Mais cakePHP ne permet donc pas réellement la localisation dans le sens où il ne formate pas les dates en fonction de la langue de l’utilisateur par exemple ? Où ai-je raté cette fonctionnalité ?

Il faut pour cela utiliser la locale et la fonction php strftime() qui se base sur la valeur de la locale pour formater correctement une date en fonction de la langue.

J’ai ce pb de février qui s’écrit sans l’accent. Y a-t-il (depuis les 6 derniers mois) une résolution plus simple que celle proposée dans l’article ‘astuces multilingue’ ? Merci

Bonjour, un peu en retard mais…

Le problème de l’accent vient de windows, en effet il ne prend pas l’UTF8 -> http://msdn.microsoft.com/en-us/library/x99tb11d.aspx

Trouvé ici: http://us.php.net/manual/en/function.setlocale.php

La seule possibilité est alors linux avec

setlocale(LC<em>TIME, 'fr</em>FR');

Edit:

setlocale(LC<em>TIME, 'fr</em>FR.utf8');

J’ai suivit le tuto et configurer le bootstrap comme tu le montre, mais les mois s’affiche toujours en anglais.

je suis sous linux, j’ai pensé que ça modifiait quelque chose j’ai donc essayé avec setlocale(LCTIME, frFR);

mais cela ne change rien.

Sous linux il faut taper la commande ‘locale -a’ pour avoir la liste des locales installées sur la machine.

merci beacoup, problème résolut. il suffisait de faire fr_FR.utf8 merci de l’aide

Bonsoir, j’aimerai effectuer une conditions de recuperation que sur l’année dans le champ DATE(en timestamp) de la ma table « posts ». Et j’aimerai savoir comment faire. Merci

Il faudrait être plus précis… Quelle est la condition que tu poses ? Ton champ est-il un timestamp, donc un entier, ou de type DATE, au format mm-jj-aaaa ?

Ceci dit je pense que la fonction YEAR() de mysql est ce que tu cherches. Tu peux donc faire un find dans ce style :

$this->find('all', array('conditions' => array('YEAR(champ_date)' => 2009)));

Merci beaucoup !!!

ça marche BRAVO

Bonjour,

Je tourne en dév sous Windows. En faisant :

setlocale(LCTIME, ‘french’); OU setlocale(LCTIME, ‘fr_FR’);

La liste des mois s’affiche toujours en anglais dans un input correspondant à un champ date. Comment faire ? Merci d’avance et bravo pour le site

Bonjour,

toujours aussi intéressante la visite de ce site est.

Débutant dans la pâtisserie, et l’anglais n’étant pas ma tasse de thé, ce site est une véritable bouée de sauvetage. J’ai déjà réglé plusieurs soucis, comme l’affichage des dates au format français.

J’ai peut-être mal cherché, mais j’ai une difficulté, en m’excusant d’avance de poser ma question à un endroit pas forcément idoïne.

Je suis pas à pas le tutoriel de blog du manuel de CakePHP, j’ai donc mis des conditions de validations comme demandé pour emêcher que les champs obligatoires soient laissés vides. Malheureusement, le message d’erreur est en anglais : « This field cannot be left blank » Comment imposer à tous les messages d’être en français ? Ou du moins, ceux qui vont parfois s’afficher sur l’écran de l’utilisateur ?

J’ai trouvé une solution pour les mois en anglais récalcitrant ‘fr_FR.iso8859-1′ ne marchant pas :

Je regle le probleme en 2nd étape une conversion unicode utf8 vers iso8859

exemple :

setlocale(LCTIME, ‘frFR.utf8′,’fra’); echo utf8_decode(strftime(« %A %d %B %Y %H:%M:%S », $udt));

Bonjour à tous,

J’ai tenté les différentes manipulations, ainsi que les solutions proposées en commentaire, mais rien ne fonctionne … (je travaille avec la version 2.1)

J’ai donc opté pour le manuel: j’ai rajouté une option ‘monthNames’ dans mon champs d’input. Si ça intéresse quelqu’un pour un petit copié/collé : ‘monthNames’ => array( ’01′ => ‘Janvier’, ’02′ => ‘Février’, ’03′ => ‘Mars’, ’04′ => ‘Avril’, ’05′ => ‘Mai’, ’06′ => ‘Juin’, ’07′ => ‘juillet’, ’08′ => ‘Août’, ’09′ => ‘Septembre’, ’10′ => ‘Octobre’, ’11′ => ‘Novemebre’, ’12′ => ‘Décembre’, )

Participez

Pour insérer une portion de code, utilisez <pre lang="php">...</pre>