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 PHPsetlocale() 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.
Commentaires
13 février 2008 à 9:18
Bonjour,
Merci pour ce tutoriel mais comment mettre en francais la fonction du helper time : timeAgoInWords ? Merci
13 février 2008 à 9:57
La méthode
timeAgoInWordsretourne 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.13 février 2008 à 10:17
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
13 février 2008 à 11:27
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
13 février 2008 à 11:42
Merci pour tes encouragements !
13 février 2008 à 16:35
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);
13 février 2008 à 16:39
Je me corrige, ce n’est pas dépendant de l’IP, mais bien de l’OS…
19 février 2008 à 16:12
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);
19 février 2008 à 17:01
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 !
19 février 2008 à 17:21
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 ??
19 février 2008 à 17:23
Mais pourtant, le fichier « bootstrap.php » est appelé dès que je fait une requête depuis mon navigateur…
19 février 2008 à 17:27
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);
19 février 2008 à 17:30
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…
19 février 2008 à 20:35
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′);
20 février 2008 à 9:54
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.
23 avril 2008 à 9:27
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 ?
23 avril 2008 à 10:03
Pour ma part, jamais. Le bootstrap reste le meilleur endroit pour définir la locale.
23 avril 2008 à 10:10
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…
16 mai 2008 à 16:00
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.
16 mai 2008 à 18:49
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…
26 mai 2008 à 13:09
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.
27 mai 2008 à 16:08
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 ?!
27 mai 2008 à 16:38
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.
6 juin 2008 à 12:21
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 ));6 juin 2008 à 12:43
Oui, à moins que les noms des mois soit une exigence du client !
6 août 2008 à 13:14
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
2 octobre 2008 à 22:48
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é ?
3 octobre 2008 à 8:33
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.
1 mars 2009 à 13:29
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
20 juin 2009 à 1:36
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
20 juin 2009 à 1:38
Edit:
16 juillet 2009 à 23:54
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.
17 juillet 2009 à 10:05
Sous linux il faut taper la commande ‘locale -a’ pour avoir la liste des locales installées sur la machine.
17 juillet 2009 à 10:10
merci beacoup, problème résolut. il suffisait de faire fr_FR.utf8 merci de l’aide
28 juillet 2009 à 20:56
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
28 juillet 2009 à 21:54
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 ?
28 juillet 2009 à 22:00
Ceci dit je pense que la fonction YEAR() de mysql est ce que tu cherches. Tu peux donc faire un find dans ce style :
29 juillet 2009 à 3:34
Merci beaucoup !!!
ça marche BRAVO
2 septembre 2009 à 17:36
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
26 septembre 2009 à 12:58
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 ?
26 janvier 2010 à 10:01
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));
25 janvier 2012 à 15:13
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’, )