Concours : calcul ordre d'arrivée

Eléphanteau du PHP | 32 Messages

07 mai 2006, 13:45

Bonjour,

J'édite pour un amis le site d'un Run&Bike et j'aimerai trouver unesolution simple de calcul de l'ordre d'arrivée des participants. Je ne sais pas sous quels format stocker le champs "temps d'arrivée" ni comment effectuer le calcul entre chaque participants.

champs temps : date(H:i:s) que je dois forcer car ce ne sera pas la date du serveur mais une date paramétrée manuellement.

Je vais créer un tableau résultat avec un tri descendant sur ce champs date mais ensuite, je ne sais pas automatiser le calcul en boucle des écarts entre chaque ligne du tableau.

EXEMPLE :
1er : équipe n°36 - temps 1h 26 min 35 secondes
2ème : équipe n°7 - temps réalisé 1h 27 min 39 sec / écart : +1 minute et 2 secondes
...

Merci pour votre aide.

http://www.runandbike.imagetheque.com

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

07 mai 2006, 15:26

Le plus simple à mon avis pour calculer les écarts, c'est de convertir tes heures en timestamp (voir la fonction mktime()). Ca te permettra de les soustraires facilement et de les reconvertir ensuite pour afficher les écarts.

Eléphanteau du PHP | 32 Messages

08 mai 2006, 00:29

J'ai essayé cette solution sans succés :

$temps est le temps réalisé.
C'est un champs "time" format h:i:s

$tempsdereference est le temps du vainqueur du même format

$timestamp = mktime($temps);
$timestamp2 = mktime($tempsdereference);
$ecart = $timestamp - $timestamp2;

$ecart=date("h:i:s",mktime($ecart));

Ca ne fonctionne pas.
Testé ici : http://runandbike.imagetheque.com/resultats1.php

ViPHP
ViPHP | 2144 Messages

08 mai 2006, 10:21

Affiche les différentes variables pour voir ce qu'elles contiennent et ainsi comprendre d'où peut venir l'erreur. et dis nous ce que ça donne.

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

08 mai 2006, 10:31

mktime -- Retourne le timestamp UNIX d'une date
Description
int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )
si $temps est au format h:i:s, je doute qu'il corresponde au premier argument attendu par la fonction mktime...

(pense à utiliser les balises [ php ] quand tu mets du codes c'est plus lisible :))

Eléphanteau du PHP | 32 Messages

08 mai 2006, 11:07

J'ai mis le champs au format DATETIME pour faciliter le calcul.

Par contre, on fouinant sur google, j'ai trouvé une fonction TIMEDIFF mais je n'arrive pas à la mettre en forme :

Exemple :
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
        -> '-00:00:00.000001'
De mon côté, je saisi le code suivant mais sans résultat :
$sql2 = mysql_query("SELECT TIMEDIFF('$temps','$tempsdereference')");        
$ecart = mysql_query($sql2); 
Où est le bug ? :?

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

08 mai 2006, 11:44

Sans doute du format... affiche nous le contenu de tes variables comme le demandait iclo :)

Quand tu dis sans résultat, c'est à dire ? dans ton script $ecart sera juste un result set qu'il te faut lire avec un mysql_fetch_quelquechose pour récuperer la valeur...

Eléphanteau du PHP | 32 Messages

08 mai 2006, 12:26

J'ai dans mon exemple un temps de référence (temps du vainqueur) le jour de l'épreuve 21 mai 2006 en l'occurence :
$tempsdereference="2006-05-21 01:00:03";
puis je calcule l'écart entre le temps réalisé ($temps par exemple 2006-05-21 01:00:15) par l'équipe et ce temps de référence dans la boucle d'affichage du tableau :

$sql = "SELECT * FROM equipe order by temps asc";
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());

while($data = mysql_fetch_array($req))
{

$temps=$data['temps'];

//calcul de l'écart

$ecart = mysql_query("SELECT TIMEDIFF('$temps','$tempsdereference')");  

//c'est ici que ça bug
// L'affichage me donne " " partout en écart.

//affichage de la ligne de résultat
//...
echo "<td align=center><span class=texte>$ecart</span></td>";
//...
$i++;
}
J'espère que je suis plus clair comme ça.
J'ai maintenant un autre probleme sur le dos car mon affichage du temp réalisé me donne la date complète 2006-05-21 01:00:00 au lieu de 01:00:00 seulement ... Je pense créer un champs supplémentaire au format TIME (pour l'affichage) en plus du champs DATETIME (pour le calul de l'écart).

http://runandbike.imagetheque.com/resultats1.php

Eléphanteau du PHP | 32 Messages

08 mai 2006, 13:18

J'ai essayé ces calculs toujours sans succés :
$temps2 = mktime($temps);
$tempsdereference2 = mktime($tempsdereference);


//1 h = 3600 secondes
//1 min = 60 secondes
$nbheure = ($temps2 - $tempsdereference2)/3600;
$nbmin = (($temps2 - $tempsdereference2)/60)-($nbheure*3600);
$nbsec = ($temps2 - $tempsdereference2)-($nbmin*60);
Ca me donne toujours 0:0:0
Je pense qu'il faut que je mette $temps sous forme (heure,min,seconde,mois,jour,anné) mais je n'y arrive pas.

http://runandbike.imagetheque.com/resultats1.php

Mammouth du PHP | 19672 Messages

08 mai 2006, 13:32

On va repartir du code précédent : tu exécutes la requête, mais tu ne récupères pas le bon résultat, correction :
<?php
$sql = "SELECT * FROM equipe order by temps asc";
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());

while($data = mysql_fetch_array($req))
{
    $temps = $data['temps'];

    //calcul de l'écart
    $sql2 = "SELECT TIMEDIFF('". $temps ."', '". $tempsdereference ."');";
    $exec = mysql_query($sql2);
    while(($ecart = mysql_result($exec, 0)) != false)
    {
        echo "<td align=center><span class=texte>". $ecart ."</span></td>";
    }
}
?>
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphanteau du PHP | 32 Messages

08 mai 2006, 13:51

Merci Cyrano mais j'ai déjà une boucle au dessous et ça ne parche pas.

J'arrive sur le bon chemin en explosant la variable $temps et en bloquant la variable $tempsdereference avec la fonction mktime.

//$temps est au format 2006-05-21 01:00:00
//on explose $temps pour isoler les heures, les minutes, les secondes

$heure1 = substr($temps,11,2);
$min1 = substr($temps,14,2);
$sec1 = substr($temps,17,2);

$temps2 = mktime($heure1,$min1,$sec1,05,21,2006);
$tempsdereference2 = mktime(01,00,00,05,21,2006);

//on fait les calculs
//1 h = 3600 secondes
//1 min = 60 secondes

$nbheure = ($temps2 - $tempsdereference2)/3600;
$nbmin = (($temps2 - $tempsdereference2)/60)-($nbheure*3600);
$nbsec = ($temps2 - $tempsdereference2)-($nbmin*60);
J'arrive bien à 0:0:0 écart sur le 1er : normal mais les autres calcul sont bizarres...

jevais garder cette piste et mettre les résulats au bon format avec des arrondis je pense.

http://runandbike.imagetheque.com/resultats1.php

Eléphanteau du PHP | 32 Messages

08 mai 2006, 13:56

Allélouia :

j'ai mis les arrondis et ça marche :
$nbheure = round(($temps2 - $tempsdereference2)/3600);
$nbmin = round((($temps2 - $tempsdereference2)/60)-($nbheure*3600));
$nbsec = round(($temps2 - $tempsdereference2)-($nbmin*60));

Eléphanteau du PHP | 32 Messages

08 mai 2006, 14:34

Voilà le code complet pour tout le monde :
//on fixe le temps du vainqueur
$tempsdereference="2006-05-21 01:00:03";

$i=1;

//on sélectionne tous les participants

$sql = "SELECT * FROM equipe order by temps asc";
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
while($data = mysql_fetch_array($req))
{
// recherche de toutes les données dont le temps de l'équipe
//....
$temps=$data['temps'];
//...


//$temps est au format 2006-05-21 01:00:00
//on explose la variable $temps

$heure1 = substr($temps,11,2);
$min1 = substr($temps,14,2);
$sec1 = substr($temps,17,2);

$temps2 = mktime($heure1,$min1,$sec1,05,21,2006);
$tempsdereference2 = mktime(01,00,00,05,21,2006);

//on effectue les calculs pour chaque equipe

//1 h = 3600 secondes
//1 min = 60 secondes
$nbheure = round(($temps2 - $tempsdereference2)/3600);
$nbmin = round((($temps2 - $tempsdereference2)/60)-($nbheure*60));
$nbsec = round(($temps2 - $tempsdereference2)-(($nbmin*60)+($nbheure*3600)));

//... code du tableau 
//on affiche le résultat

if($i>1) //on ne fait pas le clacul pour le vainqueur
{
if($nbheure>0.9999999) //si il y a + d'une heure d'écart
{
echo "+ $nbheure h : $nbmin min : $nbsec sec";
}
elseif($nbmin>1) //si il y a + d'une minute d'écart
{
echo "+ $nbmin min : $sec1 sec";
}
else //si il n'y a que des secondes d'écart
{
echo "+ $sec1 sec";
}
}

//... fin du tableau

$i++;
}

//... fin du tableau
mysql_close();
Voilà. Merci à tous.
A+
Je met "résolu".