[RESOLU] Je vous soumet une énigme à résoudre...

Eléphant du PHP | 57 Messages

27 août 2012, 23:43

Bonsoir !

Si il y'a encore parmi vous des gens qui ont les yeux ouverts et les neurones fonctionnels, je vous soumet une petite énigme issue de mon exercice de codage de ce soir. Le premier qui trouve aura droit à ma reconnaissance . Mais ne vous prenez pas trop la tête non plus, ça n'a rien de vital pour moi que cette enigme soit résolue (simplement ça me turlupine et ça m'énerve !)

situation de départ :
je veux que ma page accueil m'affiche la date et l'heure au moment ou je charge la page (dans mon exemple, il était 23h23 le 27/08/2012
j'ai donc écrit ce code :
  <?php // affichage de la date et de l'heure (h:mn) du dernier chargement de la page si le visiteur est en france. //
    date_default_timezone_set('Europe/Paris');  
// pour nous c'est date_default_timezone_set('Europe/Paris');
     
    $datetime = new DateTime('');  

 $date = date("d-m-Y");
$heure = date("H:i");
Print("Nous sommes le $date et il est $heure. <br />");
?>    
qui marche très bien et qui logiquement m'affiche : Nous sommes le 27-08-2012 et il est 23:23.

Bien ! maintenant, comme je suis, d'après mon ado de fils, une "vieille" qui aime bien les mots plutot que les chiffres, j'aurais aimé que mon navigateur m'affiche
Nous sommes le 27 aout 2012 et il est 23:23. à la place de Nous sommes le 27-08-2012 et il est 23:23.

j'ai donc eu l'idée de modifier mon code d'origine et d'écrire ceci :
 <?php // autre affichage de la date / heure courante

$date_d = date("d"); // creation de $date_d
$date_m = date("m");
$date_Y = date("Y"); // creation de $date_Y
$heure = date("H:i");

	if ('$date_m' ==01) $date_m2 = 'janvier';
	if ('$date_m' ==02) $date_m2 = 'février';
	if ('$date_m' ==03) $date_m2 = 'mars';
	if ('$date_m' ==04) $date_m2 = 'avril';
	if ('$date_m' ==05) $date_m2 = 'mai';
	if ('$date_m' ==06) $date_m2 = 'juin';
	if ('$date_m' ==07) $date_m2 = 'juillet';
	if ('$date_m' ==08) $date_m2 = 'aout';
	if ('$date_m' ==09) $date_m2 = 'septembre';
	if ('$date_m' ==10) $date_m2 = 'octobre';
	if ('$date_m' ==11) $date_m2 = 'novembre';
	if ('$date_m' ==12) $date_m2 = 'decembre';
	
Print("Nous sommes le $date_d $date_m2 $date_Y et il est $heure");
?>  
J'ai placé mon second code à la suite du premier pour que les 2 affichages soient l'un au dessus de l'autre pour les comparer + facilement.
Je m'attendait à avoir :
Nous sommes le 27-08-2012 et il est 23:23.
Nous sommes le 27 aout 2012 et il est 23:23.

Or j'ai eu (et l'énigme est là !)
Nous sommes le 27-08-2012 et il est 23:23.
Nous sommes le 27 septembre 2012 et il est 23:23

Pourquoi est ce que mon couillon de navigateur traduit 08 par septembre ? :shock: J'ai pourtant bien mis que if ('$date_m' ==08) $date_m2 = 'aout';
Je me suis même amusé à changer le mot 'septembre' dans la seconde partie du code par le mot 'tomate'
et j'ai eu :
Nous sommes le 27 tomate 2012 et il est 23:23. :mrgreen: :mrgreen: :mrgreen: Le mystère reste entier pour moi.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

28 août 2012, 00:01

salut,


franchement vu ton code ç aurait aussi bien pu être 42 :)

y a surment une raison mais je ne la connais pas.

le truc 'est que tu compare des chaine de caractère à des chiffres !!!!!

'$date_m' c'est une chaine de caractère tu compare donc la chaine '$date_m' à 8, ça n'a aucun sens.

l'auto cast de php doit faire en sort que ça soit vrai mais alors pourquoi je sais pas :mrgreen:


donc if ($date_m == 1) $date_m2 = 'janvier';

regarde sur le forum il y a des exemples plus complet et fait entièrement par php :)
avec strftime

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 57 Messages

28 août 2012, 00:16

Merci pour ta réponse Moogli !
donc si je comprends bien : ça ne marchera jamais (ou alors ce sera la faute à un gros coup de chance dont la cause est inconnue et donc la repetition est peu probable !)
Mieux vaut donc, pour l'instant, que je me contente du 27-08-2012 qui a au moins le merite d'etre juste à tout les coups !
pour le lien que tu m'a mis, je regarderais ça demain. La je me prends la tête avec un souci de cookie et après je vais faire dodo..

ViPHP
xTG
ViPHP | 7331 Messages

28 août 2012, 06:46

Histoire d'expliciter :
$var = 3;
If( '$var' == 3 )
  // $var = 3
If( $var == 3)
  // 3 = 3

Eléphant du PHP | 229 Messages

28 août 2012, 08:02

Bonjour,

Je me lance :

 setlocale(LC_TIME,fr_FR);
$datetime = strftime('%A %d %B %Y', strtotime('now'));
$heure=$heure = date("H:i");
Print("Nous sommes le $datetime et il est $heure");
Bon codage.
http://php.net/manual/fr/function.strftime.php
Et le résultat : http://ilovephp.dedicom.eu/

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

28 août 2012, 09:23

ton code indique une erreur : constante inconnue car fr_FR n'est pas une constante php (et tu ne la définie pas avant)

donc setlocale(LC_TIME,'fr_FR');

Attention ceci est soumis aux locales installées, elle n'ont pas toujours le même nom :)

mais le principe est bon.

par contre tu peux le faire en une fois pas besoin d'autant de ligne.
<?php
echo  strftime('nous sommes le %A %d %B %Y et il est %H:%M:%S', strtotime('now'));
?>
fonctionne parfaitement

Attention vérifie (au moins une fois) que setlocale ne retourne false, pour être sur de la locale utilisée :)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 229 Messages

28 août 2012, 10:00

Chez moi ca marche ^^.

Sinon tu fais comme le site php france :

"Dernière visite le Aujourd’hui, 08:08"

LOL

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

28 août 2012, 10:02

Chez moi ca marche ^^.
mwé mais c'est pas le plus important essai sur une machine sous win XP :)

y a aussi des dernières réponses hier :)

mais c'est pas la demande original Angela81 à déjà de quoi faire ;)


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 57 Messages

29 août 2012, 10:13


mais c'est pas la demande original Angela81 à déjà de quoi faire ;)


@+
Tout à fait ! merci à vous tous pour vos lumières.
Bonne journée !

ViPHP
ViPHP | 2577 Messages

29 août 2012, 11:15

Et "septembre", il sortait d'ou ? Moi, je n'ai toujours pas trouvé l'énigme...

A moins d'une blague avec changement de mois sur la machine...

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 août 2012, 12:10

Et "septembre", il sortait d'ou ? Moi, je n'ai toujours pas trouvé l'énigme...

A moins d'une blague avec changement de mois sur la machine...
Yop, je sais pas trop, faut voir du coté de l'auto cas de php je pense

parce que
if ('$date_m' ==01) $date_m2 = 'janvier';
        if ('$date_m' ==02) $date_m2 = 'février';
        if ('$date_m' ==03) $date_m2 = 'mars';
        if ('$date_m' ==04) $date_m2 = 'avril';
        if ('$date_m' ==05) $date_m2 = 'mai';
        if ('$date_m' ==06) $date_m2 = 'juin';
        if ('$date_m' ==07) $date_m2 = 'juillet';
        if ('$date_m' ==08) $date_m2 = 'aout';
        if ('$date_m' ==09) $date_m2 = 'septembre';
        if ('$date_m' ==10) $date_m2 = 'octobre';
        if ('$date_m' ==11) $date_m2 = 'novembre';
        if ('$date_m' ==12) $date_m2 = 'decembre';
s'il fournit septembre ça veux dire que l'auto cast considère que la chaîne '$date_m' est égale à 09 (sans tenir compte du type donc)

avec un test simple
<?php
$chaine = '$date_m';
$chainecast = (int)$chaine;
$chiffre = 9;
echo '<pre>';
debug_zval_dump($chaine);
echo '</pre><hr />';
echo '<pre>';
debug_zval_dump($chainecast);
echo '</pre><hr />';
echo '<pre>';
debug_zval_dump($chiffre);
echo '</pre><hr />';
if ('$date_m' == $chiffre)
	echo 'ouch';
else 
	echo 'ça va !';
le résultat est
string(7) "$date_m" refcount(2)

long(0) refcount(2)

long(0) refcount(2)

ouch
donc php stock bien le premier en chaîne de caractères.
et le chiffre en long mais il ne garde que zéro comme valeur (je ne sais pas pourquoi)

Le cast de la chaine de caractère en entier retourne zéro (je ne sais pas pourquoi non plus)

Donc le test compare une chaîne de caractère à zéro, ce qui revient avec, l'auto cast à comparer zéro avec zéro.
le test est donc vrai :)

Maintenant pourquoi septembre ?

c'est simple.
Le teste est vrai pour tout les cas de janvier à septembre, car à chaque fois la zval contient zéro ! (ceci a cause du zéro en tête).
les tests étant fait tous les un à la suite des autres date_m2 passe successivement de janvier à septembre.

pour les trois derniers mois, on compare 10, 11 ou 12 à zéro. ces tests ne peuvent pas être vrai.

Le problème ici est lié
- à une mauvaise utilisation de la syntaxe php : d'une manière générale il ne faut pas mettre des variables dans les chaines de caractères. la preuve ici au lieu de " angela à utilisée des ' et ça fou la merde. la concaténation sert à ça, de plus même "$var" n'est pas défendable, aucun intérêt de faire fonctionner le parse de chaîne de caractère pour rien :)
- A un cast, qui peux se comprendre, une chaine de caractère ce n'est pas un chiffre, cette chaine ne commence pas par un chiffre, donc valeur par défaut zéro !

voila pourquoi septembre :)

Si tu veux t'en convaincre utilise un debugguer et regarde où passe le script :)

C'est pour cela que souvent les gens préfères les systèmes typé y a moins de soucis de se genre :)

@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 2278 Messages

29 août 2012, 12:30

C'est tellement plus simple ainsi:
<?php // autre affichage de la date / heure courante

$date_d = date("d"); // creation de $date_d
$date_m = date("m");
$date_Y = date("Y"); // creation de $date_Y
$heure = date("H:i");
$mois = array( "01"=>"janvier","02"=>"f&eacute;vrier", "08"=>"ao&ucirc;t");
$date_m2 = $mois[$date_m];
 print "$date_m2";
 ?>
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 août 2012, 13:13

dans le cas qui nous intérresse plutot comme ça php-debutant/vous-soumet-une-enigme-res ... ml#p394072

Autant ne pas réutiliser la roue.

sinon autre alternative avec un tableau indexé numériquement et date('n').

le tabelau apport l'avantage de lever le problème de l'encodage, ceci dit avec la locale devrait pas y en avoir, mais la j'ai pas testé.


quand au print "$date_m2"; j'ai déjà donné mon avis avant :s ^^


@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 2278 Messages

29 août 2012, 17:12

Autant ne pas réutiliser la roue.
Il vaut peut être mieux "réutiliser la roue." que de la réinventer.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 août 2012, 17:32

ouch, effectivement boullette :oops:
Il en faut peu pour être heureux ......