Calculer la différence de jours

Résolu/Fermé
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 - Modifié par jobouille le 3/08/2015 à 22:01
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 - 4 août 2015 à 23:24
Bonjour à tous !
Je vous explique mon problème, sur mon site j'affiche un message de la dernière connexion d'un membre (afin que les autres membres puissent voir quand es ce que ce membre a été dernièrement connecté).
Pour cela il y a une date dans la bdd de chaque membre lorsqu'il se connecte.

Donc pour afficher la dernière connexion, il faut faire la différence de la date de celle de la bdd par rapport à la date actuelle.

J'ai fais ce code (qui contient pas mal de if, ce qui me dérange) mais il y a un problème.

$datetime1 = strtotime($donnees['derniereCo']);
$now = date('Y-m-d H:i:s');
$datetime2 = strtotime($now);
           
$interval  = abs($datetime2 - $datetime1);
$hours= round($interval / 3600); 

if($hours < 24)
{
 $msg_derniereCo = "Aujourd'hui";
}
if($hours >= 24 AND $hours < 48)
{
 $msg_derniereCo = "Hier";
}
if($hours >= 48 AND $hours < 72)
{
 $msg_derniereCo = "Il y a 2 jours";
}
if($hours >= 72 AND $hours < 96)
{
 $msg_derniereCo = "Il y a 3 jours";
}
if($hours >= 96 AND $hours < 120)
{
 $msg_derniereCo = "Il y a 4 jours";
}
if($hours >= 120 AND $hours < 144)
{
 $msg_derniereCo = "Il y a 5 jours";
}
if($hours >= 144 AND $hours < 168)
{
 $msg_derniereCo = "Il y a 6 jours";
}
if($hours >= 168 AND $hours < 192)
{
 $msg_derniereCo = "Il y a 1 semaine";
}
if($hours >= 192)
{
 $msg_derniereCo = "Il y a plus d'une semaine !";
}


Me problème étant que si le membre se connecte un Mardi à 22h par exemple. Le lendemain (avant 22h) on verra "Dernière connexion : Aujourd'hui". Car mon code calcul les heures et pas les jours.

Il faudrait en fait calculer la différence des jours afin que dès que minuit passe, cela fasse 1 jour de plus.

Je ne sais pas si je me suis bien exprimé mais j'espère que vous saurez m'aider.

Merci et bonne journée/soirée.

2 réponses

NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
3 août 2015 à 22:47
Déjà, tu peux simplifié en utilisant elseif :


if($hours < 24)
{
 $msg_derniereCo = "Aujourd'hui";
}
elseif($hours < 48)
{
 $msg_derniereCo = "Hier";
}
elseif($hours < 72)
{
 $msg_derniereCo = "Il y a 2 jours";
}
else
{
 $msg_derniereCo = "Trop longtemps";
}



Ensuite, tu peux aussi faire un tableau :
$Duree=array();
$Duree[]=array(24,"Aujourd'hui");
$Duree[]=array(48,"Hier");
...

Puis une boucle :
$Texte="";
for($i,$i<count($Duree);$i++)
    if($Duree[$i][0]>$hours)
        $Texte=$Duree[$i][1];
if($Texte=="")
    $Texte="Trop longtemps";

0
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 10
3 août 2015 à 23:05
Je suis plutôt débutant et je n'ai pas très bien compris ce "tableau".

Merci de m'avoir répondu et il est vrai que je n'avais pas pensé à "raccourcir" le code de cette manière-ci.
Cependant le problème reste le même :/

Merci
0
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
4 août 2015 à 00:16
Pour le tableau, chaque :
$Duree[]=array(...,"...");
Ajoute une entrée à la fin du tableau.
Les entrées sont composées d'un autre tableau avec en premier, le nombre d'heure et en second le texte à afficher.

Ensuite la boucle va permettre de chercher l'entrée qui est la première à matcher (d'ailleurs, il y a un petit bug, voir plus bas dans mon message), si rien n'est trouvé, c'est que c'est hors tableau donc on affiche un texte par défaut.

    if($Duree[$i][0]>$hours)
        $Texte=$Duree[$i][1];

est à remplacer par :
    if($Duree[$i][0]>$hours)
    {
        $Texte=$Duree[$i][1];
        break;
    }
0
Déjà pour gagner une ligne, au lieu de faire ça:

$now = date('Y-m-d H:i:s');
$datetime2 = strtotime($now);


La fonction time() est faite pour ça:

$datetime2 = time();


Et là avec le code que tu montres, tu peux comprimer encore plus:

$now = date('Y-m-d H:i:s');
$datetime2 = strtotime($now);
           
$interval  = abs($datetime2 - $datetime1);
$hours= round($interval / 3600); 


Devient:

$hours = round((time() - $datetime1)/ 3600);


Car si ton système est bien foutu, normalement un membre ne peut pas écrire un message dans le futur, du coup le abs n'est pas utile car la date du message sera toujours inférieure à celle actuelle.

Mais vaut mieux faire un floor, car un round arrondi au dessus si c'est supérieur à .5, donc tu peux avoir il y a 2 jours au lieu de hier.

Donc:

$hours = floor((time() - $datetime1)/ 3600);


Et petit conseille, enregistre les dates avec le timestamp directement et non la date, le timestamp est plus simple à utiliser. Du moins tu en fait un peu ce que tu veux car, si tu veux par exemple juste avoir le jour (Lundi, Mardi...) Tu dois convertir ta date en timestamp puis la reconvertir pour avoir le jour.

Après pour éviter tout les if il y a le switch/case ( https://www.php.net/manual/fr/control-structures.switch.php )

Il vas tester une valeur avec plusieurs résultat, et si l'un d'eux est correct, il exécute la commande associé, car si tu regardes tu utilises des multiples de 24, du coup ça revient à 1x24, 2x24.

Ce qui donne:

switch (ceil($hours/24)) {
 case 0:
  $msg_derniereCo = "Aujourd'hui";
  break;
 case 1:
  $msg_derniereCo = "Hier";
  break;
 case 2:
  $msg_derniereCo = "Il y a 2 jours";
  break;
 case 3:
  $msg_derniereCo = "Il y a 3 jours";
  break;
 case 4:
  $msg_derniereCo = "Il y a 4 jours";
  break;
 case 5:
  $msg_derniereCo = "Il y a 5 jours";
  break;
 case 6:
  $msg_derniereCo = "Il y a 6 jours";
  break;
 case 7:
  $msg_derniereCo = "Il y a 1 semaine";
  break;
 default:
  $msg_derniereCo = "Il y a plus d'une semaine !";
  break;
}


On peut même aller plus loin car si tu remarques la case 2, 3, 4, 5 et 6 on le même message, on obtient alors:

switch (ceil($hours/24)) {
 case 0:
  $msg_derniereCo = "Aujourd'hui";
  break;
 case 1:
  $msg_derniereCo = "Hier";
  break;
 case 2:
 case 3:
 case 4:
 case 5:
 case 6:
  $msg_derniereCo = "Il y a ".floor($hours/24)." jours";
  break;
 case 7:
  $msg_derniereCo = "Il y a 1 semaine";
  break;
 default:
  $msg_derniereCo = "Il y a plus d'une semaine !";
  break;
}


Enfin pour répondre à ton problème , tu peux comparer le jour, si on est le 03 ou le 04:

case 0:
 if (date('d') == date('d', $datetime1)) {
  $msg_derniereCo = "Aujourd'hui";
 } else {
  $msg_derniereCo = "Hier";
 }
 break;


Et si tu veux encore plus comprimé, il y a la condition ternaire:

case 0:
 $msg_derniereCo = (date('d') == date('d', $datetime1)) ? "Aujourd'hui" : "Hier" ;
 break;


J'espère t'avoir aidé et appris des trucs, au final ton code peut ressembler à ça:

$datetime1 = strtotime($donnees['derniereCo']);
$hours = floor(floor((time() - $datetime1)/ 3600)/24);
switch ($hours) {
 case 0:
  $msg_derniereCo = (date('d') == date('d', $datetime1)) ? "Aujourd'hui" : "Hier" ;
  break;
 case 1:
  $msg_derniereCo = "Hier";
  break;
 case 2:
 case 3:
 case 4:
 case 5:
 case 6:
  $msg_derniereCo = "Il y a ".$hours." jours";
  break;
 case 7:
  $msg_derniereCo = "Il y a 1 semaine";
  break;
 default:
  $msg_derniereCo = "Il y a plus d'une semaine !";
  break;
}
0
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 10
3 août 2015 à 23:50
Merci beaucoup de votre réponse complète !
Cela m'a effectivement appris pas mal de chose.

Cependant le message affiché est toujours "Il y a plus d'une semaine !".
Comme s'il prenait cette valeur par défaut sans tenir compte des autres.
J'ai pourtant changer ma colonne en TIMESTAMP (et non datetime) et je n'ai pas modifié le code :
$datetime1 = $donnees['derniereCo'];
$hours = floor(floor((time() - $datetime1)/ 3600)/24);
switch ($hours) {
case 0:
$msg_derniereCo = (date('d') == date('d', $datetime1)) ? "Aujourd'hui" : "Hier" ;
break;
case 1:
$msg_derniereCo = "Hier";
break;
case 2:
case 3:
case 4:
case 5:
case 6:
$msg_derniereCo = "Il y a ".$hours." jours";
break;
case 7:
$msg_derniereCo = "Il y a 1 semaine";
break;
default:
$msg_derniereCo = "Il y a plus d'une semaine !";
break;
}


Encore merci de votre aide :D
0
Utilisateur anonyme
3 août 2015 à 23:53
Vérifie le Timestamp alors, il y a un truc incorrect, car si tu remplaces:

$datetime1 = $donnees['derniereCo'];


Par:

$datetime1 = strtotime('-2 hours');


Ou:

$datetime1 = strtotime('-2 days');


Ça retourne aujourd'hui ou il y a 2 jours
0
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 10
3 août 2015 à 23:59
Effectivement ça me met "Aujourd'hui" avec le premier datetime1 et "Il y a 2 jours" avec l'autre.

Comment je peux faire pour vérifier le timestamp ?

Merci
0
Utilisateur anonyme
4 août 2015 à 00:02
Fait un var_dump de ta variable donc var_dump($datetime1); Comme ça tu veras le contenu de la variable.
0
jobouille Messages postés 286 Date d'inscription jeudi 11 juin 2009 Statut Membre Dernière intervention 27 septembre 2017 10
4 août 2015 à 00:07
Ça m'affiche ceci : string(19) "2015-08-04 00:01:39"
Il y a donc ce " string(19) " suivi de la date de la bdd du membre.
0