8721 sujets

Développement web côté serveur, CMS

j'ai un problème:


je déclare un champ d'une base mysql en tant que timestamp avec comme valeur par défaut CURRENT_TIMESTAMP

je crée un enregistrement à 17h06.

ensuite à 17h26 j'exécute ce code ($not_dispo->timing étant le champ en question)

	
echo (time() - strtotime($not_dispo->timing))/60 .'<br />';


je m'attends à trouver environ 20 (mn) et le résultat est -40.45

je comprends pas pourquoi

(edit) à 17h36 il m'affiche -30.33 ..... on dirait que c'est le complémentaire à 1h, y a pas une histoire d'heure d'hiver?
Modifié par lionel_css3 (09 Jan 2013 - 17:39)
à 18h06, j'ai pratiquement 0
on dirait bien qu'il y a une heure d'écart, pourtant, dans la base mysql le champ est bien à 17h06

(2013-01-09 17:06:42)
Bonsoir !

Je suis prêt à parier que le timestamp retourné par PHP (via time()) et celui stocké dans votre base MySQL ne sont pas basés sur le même fuseau horaire.

Par ailleurs, le type de données "timestamp" en MySQL ne stocke pas le fuseau horaire, utilisez plutôt le type de données "datetime".

Cet article devrait vous intéresser : http://dev.mysql.com/doc/refman/5.6/en/datetime.html

Attention aussi avec le format "timestamp", il y a une subtilité (que je trouve particulièrement foireuse, avis perso) : MySQL considère que la première colonne de type "timestamp" dans une table doit automatiquement être mise à jour lorsque l'on fait un UPDATE. Plus de précisions sur http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html

Pour résoudre votre problème, je pense que vous devriez envisager de modifier ce champ timestamp vers datetime (pour avoir le fuseau horaire), et que vous ne devriez pas utiliser la fonction time() de PHP, mais bien la fonction NOW().

Par ailleurs, il y a une fonction toute dédiée pour vous : TIMEDIFF(), ce qui donne ceci :

mysql> SELECT TIMEDIFF(NOW(), '2013-01-09 17:06:42');
+----------------------------------------+
| TIMEDIFF(NOW(), '2013-01-09 17:06:42') |
+----------------------------------------+
| 02:50:49                               |
+----------------------------------------+
1 row in set (0.00 sec)


Mais ce n'est pas encore suffisant, ce qui vous intéresse, c'est le nombre de minutes, au diable les secondes et les heures !

Alors, on va encore faire travailler le SGBD à votre place, et lui confier la tâche !
Et on va se servir de la fonction TIME_TO_SEC() qui va nous donner le nombre de secondes :

mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), '2013-01-09 17:06:42'))/60;
+--------------------------------------------------------+
| TIME_TO_SEC(TIMEDIFF(NOW(), '2013-01-09 17:06:42'))/60 |
+--------------------------------------------------------+
|                                               174.6500 |
+--------------------------------------------------------+
1 row in set (0.00 sec)


Mais... peut-être que cette décimale va vous enquiquiner alors... tant qu'à faire travailler le SGBD, on va le faire jusqu'au bout, en utilisant FLOOR() qui va arrondir à la minute inférieure (donc 1,3 minute donnera 1) ce qui donne ceci :


mysql> SELECT FLOOR(TIME_TO_SEC(TIMEDIFF(NOW(), '2013-01-09 17:06:42'))/60);
+---------------------------------------------------------------+
| FLOOR(TIME_TO_SEC(TIMEDIFF(NOW(), '2013-01-09 17:06:42'))/60) |
+---------------------------------------------------------------+
|                                                           174 |
+---------------------------------------------------------------+
1 row in set (0.01 sec)


Dernière précision (mais je suppose que vous le saviez déjà), remplacez la chaine '2013-01-09 17:06:42' par le nom de votre colonne ! Smiley smile

J'espère que cela solutionnera votre problème, tenez-nous au courant ! Smiley smile

Bonne soirée !
Modifié par Bouchon (09 Jan 2013 - 20:08)
Merci beaucoup Bouchon pour avoir pris le temps de me répondre avec autant de précision, je vais étudier tout ça à tête reposée.

note: ma base st sur wamp lors de mes essais
j'ai commencé à étudier ça mais il semble qu'avec un champ datetime on ne peut pas mettre une valeur pas défaut comme CURRENT_TIMESTAMP alors que ce que je veux faire repose là dessus.
Ou alors il faudrait que j'insère l'heure courante dans le champ lors de sa création?
lionel_css3 a écrit :
j'ai commencé à étudier ça mais il semble qu'avec un champ datetime on ne peut pas mettre une valeur pas défaut comme CURRENT_TIMESTAMP alors que ce que je veux faire repose là dessus.
Ou alors il faudrait que j'insère l'heure courante dans le champ lors de sa création?


Oui il faut que tu l'insères avec la fonction NOW(). Franchement les champs timestamp c'est la merde (ça pose plus de problème que ça en résout) et ça sert vraiment plus à rien. Y'a 10 ans c'était utile pour grappiller un peu côté performance mais aujourd'hui ça n'a aucun intérêt.
ah d'accord, merci jb_gfx je peux faire ça avec une requête du style

INSERT INTO table_name (column1)
VALUES (NOW()) ??

ça marche?
voila, grâce à vos conseils j'ai résolu mon problème.

je créé le champ avec une requête de ce style


 $insert_being = $DB->insert('INSERT INTO being (id_item, timing) VALUES ('.$k.', NOW())');


et quand je veux le tester, je l'extraie de cette façon


$show_not_dispo_in_being = $DB->query('SELECT id, id_item, TIME_TO_SEC(TIMEDIFF(NOW(), `timing`)) as diff FROM being');


après, je teste simplement la valeur en secondes


foreach($show_not_dispo_in_being as $not_dispo):
	if ($not_dispo->diff > 600):  // on traite si > 10mn
// suite du code


votre aide m'a été précieuse... Smiley biggrin encore merci