DÉBUTANT : FONCTION POUR TRANSFORMER UN TEMPS EN SECONDES EN JOUR HEURE MINUTE S

lefter Messages postés 63 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 16 mai 2009 - 14 nov. 2009 à 12:46
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 - 17 nov. 2009 à 00:55
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/50848-debutant-fonction-pour-transformer-un-temps-en-secondes-en-jour-heure-minute-seconde

Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
17 nov. 2009 à 00:55
MonkeyIsBack -> J'aimerais tout d'abord souligner que ton benchmark est biaisé. Quand tu fais une boucle sur une même partie de code, la partie qui est en boucle est précompilé à la deuxième itération ce qui permet un temps d'exécution beaucoup plus rapide surtout si le code utilise uniquement de l'arithmétique. Dans le cas des fonctions natives, ils sont compilées généralement dans des dll. Quand tu utilises des fonctions natives en boucles, le temps d'exécution à la première itération est généralement très proche de celui de la deuxième. Ce que ton benchmark a mesuré c'est la vitesse d'exécution de ton code quand il est précompilé par PHP.

Dans le cas de fonction pour transformer du temps en lettre, l'utilisation dans un page ce limite souvent à une ou à quelques utilisations. Dans ce cas, les fonctions natives sont à privilégier puisqu'ils sont déjà précompilés dans des dll. Si tu aurais fais des benchmarks sur le temps de première itération pour les deux fonctions, la fonction date aurait été la plus rapide.

P.S.: Des benchmarks c'est souvent comme des statistiques, on peut faire dire pratiquement n'importe quoi avec.
abdou1950 Messages postés 6 Date d'inscription mercredi 28 novembre 2007 Statut Membre Dernière intervention 20 janvier 2008
16 nov. 2009 à 17:07
Bonjour,

Voila, j'ai téléchargé le zip du programme de transformation du temps en sevcondes, minutes et heures, mais je ne sais pas comment l'éxecuter, ( je suis vraiment trés débutant).

Salutations
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 nov. 2009 à 13:10
Au temps pour moi, Arto a fait une erreur dans le format de la date ^^

Mais je persiste sur mon commentaire précédent... Ton code est quand même beaucoup moins clair.
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
16 nov. 2009 à 12:11
Voici ma source actuelle sur mon site (et qui fonctionne vu que je l'ai vérifié à l'usage ^^)

function Convert_Sec_JHms($Seconde)
{
// Transformation Secondes en Jour Heure minute seconde
$Jour = floor($Seconde / 86400);
$Seconde = $Seconde - ($Jour * 86400); // Parenthèse facultative
$Heure = floor($Seconde / 3600);
$Seconde = $Seconde - ($Heure * 3600);
$Minute = floor($Seconde / 60);
$Seconde = $Seconde - ($Minute * 60);

// Ajout des zéros au cas où l'affichage soit en dessous de 10
if ($Heure < 10)
{$Heure = '0'.$Heure;}
if ($Minute < 10 AND $Minute > 0)
{$Minute = '0'.$Minute;}
if ($Minute == 0)
{$Minute = '00';}
if ($Seconde < 10)
{$Seconde = '0'.$Seconde;}

// Retourne une variable la plus petite possible
if ($Jour > 0)
{return $Jour.'j '.$Heure.':'.$Minute.':'.$Seconde;}
elseif ($Heure > 0)
{return $Heure.':'.$Minute.':'.$Seconde;}
else
{return $Minute.':'.$Seconde;}
}

PS : ma fonction ne donne aucune erreur possible, quelque soit le nombre de secondes, tout est exact à l'unité près ;-) (j'ai vérifié toutes les valeurs genre 60 seconde => 01:00, 3600 => 01:00:00, également pour le nombre de jours etc etc
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 nov. 2009 à 12:09
Ah mince, j'ai cliqué trop tôt, j'avais encore quelque chose à dire...
Le temps obtenu de 1.2 secondes est pour 200000 itérations... Ce qui veut dire que sur une seule exécution, la différence est vraiment dérisoire (en physique on parle de négligeable).
Il ne faut donc pas se focaliser trop sur les performances : mieux vaut accorder de l'importance à un code concis, qui ne laisse pas de place à l'erreur, facile à lire et à comprendre et donc facile à corriger/maintenir.
Suivant ces critères objectifs, le code d'Arto est le "meilleur".
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 nov. 2009 à 12:06
Le code d'Arto est environ 2 fois plus rapide que celui de ta source actuelle.
D'ailleurs, le résultat n'est pas le même (je pense que celui d'Arto a plus de chances d'être le bon du fait que le traitement effectué ne laisse pas de place à l'erreur). Autrement dit, ta source renvoit un résultat erroné.

Pour ce qui est des modifications que tu apportes au fur et à mesure, ce serait bien d'avoir la source complète avec... J'ai bien essayé de faire une fonction en collant les morceaux, mais elle me retourne 00:00 qui n'est manifestement pas le résultat attendu...

J'ai mis le code de mon bench ici : http://tools.codes-sources.com/copy-paste-code.aspx?ID=244
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
16 nov. 2009 à 11:30
Allez je continue sur ma propre lancée ...

Voici un remaniement de la fin de la fonction :

// Retourne une variable la plus petite possible
if ($Jour > 0)
{return $Jour.'j '.$Heure.':'.$Minute.':'.$Seconde;}
elseif ($Heure > 0)
{return $Heure.':'.$Minute.':'.$Seconde;}
else
{return $Minute.':'.$Seconde;}
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
16 nov. 2009 à 11:20
Ouep.

Cependant j'ai fait des "benchmarks" (regardes un peu plus haut dans les commentaires), et niveau performances, c'est bel et bien mon bout de script avec des while qui était plus rapide, donc si on privilégie les performances, la toute dernière "version" est bel et bien la meilleure, même si elle ne fait pas appel à la fonction date initialement prévue à cet effet (et à d'autres d'ailleurs même si elle se révèle bien plus pratique pour l'affichage du nom des jours par exemple ...)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 nov. 2009 à 11:15
Ben concrètement, là tu ne réinventes pas la division euclidienne, donc oui, c'est forcément mieux.
Mais il n'en reste pas moins que les méthodes proposées qui font ça en deux lignes sont ENCORE plus efficaces... ;)
Notamment les deux lignes d'Arto sont, à mon sens, la solution à privilégier. Elle pourrait être postée sur Codyx, si une telle fonction n'y figure pas déjà.

Merci de ne pas t'être vexé à la lecture de ma critique (je le craignais un peu, certains ici s'enflamment pour moins que ça) et de la prendre de manière constructive.
Au final, ta source n'a pas sa place ici, mais sa publication aura eu le mérite d'exposer ton code à la critique et de te faire progresser, donc c'est quand même une bonne chose.

Bonne continuation.
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
16 nov. 2009 à 11:05
Effectivement, tu as parfaitement raison !
Voici donc le nouveau code, encore plus efficace, merci pour ta critique / remarque :

$Jour = floor($Seconde / 86400);
$Seconde = $Seconde - ($Jour * 86400); // Parenthèse facultative
$Heure = floor($Seconde / 3600);
$Seconde = $Seconde - ($Heure * 3600);
$Minute = floor($Seconde / 60);
$Seconde = $Seconde - ($Minute * 60);

Est-ce la bonne méthode ?
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
16 nov. 2009 à 10:46
Salut,

Concernant cette source qui n'en est finalement pas une (mais plutôt un snippet à poster sur codyx), tuot a été dit...
Concernant le code, personne ne semble avoir été choqué par cette étrange pratique qui consiste à utiliser while pour faire une division à l'aide de soustractions... :

while ($Seconde >= 86400){$Jour $Jour + 1; $Seconde $Seconde - 86400;}
while ($Seconde >= 3600){$Heure $Heure + 1; $Seconde $Seconde - 3600;}
while ($Seconde >= 60){$Minute $Minute + 1; $Seconde $Seconde - 60;}

Que l'on me pardonne, mais ce morceau de code est franchement dégueulasse... Oui, dans les propositions qui ont été faites, il a été remplacé. Mais il me paraît important d'avertir l'auteur qu'écrire du code comme ça, c'est vraiment crade... On pourrait aussi reproduire en PHP les instructions en Langage Machine, ça fonctionnerait... Mais quel gaspillage d'énergie et de ressources système pour faire justement ce dont un langage de haut niveau permet de se dispenser.
Arto_8000 Messages postés 1044 Date d'inscription lundi 7 mars 2005 Statut Membre Dernière intervention 13 juillet 2010 7
14 nov. 2009 à 16:41
C'est inutile d'appeler 3 fois la méthode date quand on peut tout faire en un appel ...

function Convert_Sec_JHmsB($Seconde){
if ($Secondes>86400)
return (floor($Secondes/86400)).'j '.date('G:s:i',$Secondes);
return date('G:i:s',$Secondes);
}
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
14 nov. 2009 à 16:30
PS : zut, n'ayant pas bougé ma propre fonction d'où elle était (dans un include, c'est une fonction dont moi même je me sers), le résultat c'est que le code que j'ai filé au dessus est faux =>

Convert_Sec_JHmsA($randA);

Dans la boucle ;)

Note : le temps d'execution d'une seule fois les fonctions : (puisqu'on y est ><) et donc approximativement :
Calcul précédent de 10 000 fois la fonction - 10 000 génération d'aléatoire & boucle :P 12.383121 - 0.005005 secondes / 10 000> 1,2 milliseconde pour une execution de ma fonction, et 1,6 pour la sienne ^^
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
14 nov. 2009 à 16:24
Erf il n'y a pas de fonction éditer :S

Je me suis demandé si quelques simples calculs de variables n'étaient pas plus rapides qu'appeller la fonction date, à ce sujet, j'ai donc décidé de me pencher sur la question et ai réalisé un simple benchmark ...

le voici pour les deux fonctions, la tienne et la mienne (je n'ai d'ailleurs même pas testé l'affichage de la tienne, j'ai copié la deuxième uniquement ^^...

Voici ce que PHP me retourne :

Premiere fonction :12.383121 milliseconde pour 10 000 executions
Deuxieme fonction :16.192253 milliseconde pour 10 000 executions

et le code du bench

function Convert_Sec_JHmsA($Seconde)
{
// Transformation Secondes en Jour Heure minute seconde
while ($Seconde >= 86400){$Jour $Jour + 1; $Seconde $Seconde - 86400;}
while ($Seconde >= 3600){$Heure $Heure + 1; $Seconde $Seconde - 3600;}
while ($Seconde >= 60){$Minute $Minute + 1; $Seconde $Seconde - 60;}

// Ajout des zéros au cas où l'affichage soit en dessous de 10
if ($Heure < 10)
{$Heure = '0'.$Heure;}
if ($Minute < 10 AND $Minute > 0)
{$Minute = '0'.$Minute;}
if ($Minute == 0)
{$Minute = '00';}
if ($Seconde < 10)
{$Seconde = '0'.$Seconde;}

// Retourne une variable la plus petite possible
if ($Jour > 0)
{$Convert = $Jour.'j '.$Heure.':'.$Minute.':'.$Seconde; return $Convert;}
elseif ($Heure > 0)
{$Convert = $Heure.':'.$Minute.':'.$Seconde; return $Convert;}
elseif ($Minute > 0)
{$Convert = $Minute.':'.$Seconde; return $Convert;}
else
{$Convert = '00:'.$Seconde; return $Convert;}
}

function Convert_Sec_JHmsB($Seconde){
if ($Secondes>86400)
return (floor($Secondes/86400)).'j '.date('G',$Secondes).':'.date('i',$Secondes).':'.date('s',$Secondes);
return date('G',$Secondes).':'.date('i',$Secondes).':'.date('s',$Secondes);
}

$i = 0;
$timeparts = explode(' ',microtime());
$starttime = $timeparts[1].substr($timeparts[0],1);
while ($i< 1000){
++$i;
$randA = rand(0, 500000);
Convert_Sec_JHms($randA);
}
$timeparts = explode(' ',microtime());
$endtime = $timeparts[1].substr($timeparts[0],1);
echo 'Premiere fonction :',bcsub($endtime,$starttime,6),' milliseconde pour 10 000 executions
';

$i = 0;
$timeparts = explode(' ',microtime());
$starttime = $timeparts[1].substr($timeparts[0],1);
while ($i< 1000){
++$i;
$randB = rand(0, 500000);
Convert_Sec_JHmsB($randB);
}
$timeparts = explode(' ',microtime());
$endtime = $timeparts[1].substr($timeparts[0],1);
echo 'Deuxieme fonction :',bcsub($endtime,$starttime,6),' milliseconde pour 10 000 executions';
MonkeyIsBack Messages postés 9 Date d'inscription vendredi 13 novembre 2009 Statut Membre Dernière intervention 27 juin 2011
14 nov. 2009 à 16:10
Effectivement ! La fonction date ... serais-je bète ...

J'ai toute fois un doute, je me demande ce qui est le plus performant. Appeler une fonction complexe cinq fois de suite ou effectuer de simples calculs de variables ^^...

Sinon ta solution est bien plus propre en effet ;-)
lefter Messages postés 63 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 16 mai 2009
14 nov. 2009 à 12:51
function Convert_Sec_JHms($Seconde){
if ($Secondes>86400)
return (floor($Secondes/86400)).'j '.date('G',$Secondes).':'.date('i',$Secondes).':'.date('s',$Secondes);
return date('G',$Secondes).':'.date('i',$Secondes).':'.date('s',$Secondes);
}
lefter Messages postés 63 Date d'inscription lundi 7 juin 2004 Statut Membre Dernière intervention 16 mai 2009
14 nov. 2009 à 12:46
Un code un peu plus court :

function Convert_Sec_JHms($Seconde){
return (floor($Secondes/86400)).'j '.date('G',$Secondes).':'.date('i',$Secondes).':'.date('s',$Secondes);
}
Rejoignez-nous