web-dev-qa-db-fra.com

Que peut utiliser pour DateTime :: diff () pour PHP 5,2?

Existe-t-il une fonction équivalente à DateTime :: diff () dans PHP 5.2?

Mon serveur local est PHP 5.3 et utilise DateTime :: diff (). alors j'ai trouvé que mon site actif utilise PHP 5.2 et donne une erreur.

Fatal error: Call to undefined method DateTime::diff() in /var/www/some/other/dir/web/daikon/modules/projects/views/admin/log/admin_log_list.php on line 40

Le code PHP:

 foreach ($logs as $key => $list){
 ...
 // show date in European way dd-mm-yyyy not in MySQL way yyyy-mm-dd
    $newdate =new DateTime($list['date']) ;
    echo "<td class=\"left\" width=\"8%\">".$newdate->format('d-m-Y')."</td>\n";
    $starttime = new DateTime($list['start_time']);
    echo "<td width=\"7%\">".date_format($starttime, 'H:i')."</td>\n";
    $finishtime = new DateTime($list['finish_time']);
    echo "<td width=\"8%\">".date_format($finishtime, 'H:i')."</td>\n";
    $timediff = 0;
    $interval = $starttime->diff($finishtime);
    $hours   = $interval->format('%h');
    $minutes = $interval->format('%i');
    $timediff = $hours * 60 + $minutes;
25
shin

La réponse de Spudley ne fonctionne pas pour moi - soustraire tout DateTime d'un autre donne 0 sur mon système.

J'ai pu le faire fonctionner en utilisant DateTime :: format avec le spécificateur 'U' (secondes depuis Epoch Unix):

$start = new DateTime('2010-10-12');
$end = new DateTime();
$days = round(($end->format('U') - $start->format('U')) / (60*60*24));

Cela fonctionne à la fois sur mon système de développement (5.3.4) et sur mon système de déploiement (5.2.11).

39

J'en avais juste besoin (malheureusement) pour un plugin WordPress. J'utilise cette fonction en 2 fois:

  1. Dans ma classe, appeler -> diff () (ma classe s'étend DateTime , alors$ thisest la référence DateTime )

    function diff ($secondDate){
        $firstDateTimeStamp = $this->format("U");
        $secondDateTimeStamp = $secondDate->format("U");
        $rv = ($secondDateTimeStamp - $firstDateTimeStamp);
        $di = new DateInterval($rv);
        return $di;
    }
    
  2. Ensuite, j'ai recréé une fausse classe DateInterval (car DateInterval n'est valide que dans PHP> = 5.3) comme suit: 

    Class DateInterval {
        /* Properties */
        public $y = 0;
        public $m = 0;
        public $d = 0;
        public $h = 0;
        public $i = 0;
        public $s = 0;
    
        /* Methods */
        public function __construct ( $time_to_convert /** in seconds */) {
            $FULL_YEAR = 60*60*24*365.25;
            $FULL_MONTH = 60*60*24*(365.25/12);
            $FULL_DAY = 60*60*24;
            $FULL_HOUR = 60*60;
            $FULL_MINUTE = 60;
            $FULL_SECOND = 1;
    
    //        $time_to_convert = 176559;
            $seconds = 0;
            $minutes = 0;
            $hours = 0;
            $days = 0;
            $months = 0;
            $years = 0;
    
            while($time_to_convert >= $FULL_YEAR) {
                $years ++;
                $time_to_convert = $time_to_convert - $FULL_YEAR;
            }
    
            while($time_to_convert >= $FULL_MONTH) {
                $months ++;
                $time_to_convert = $time_to_convert - $FULL_MONTH;
            }
    
            while($time_to_convert >= $FULL_DAY) {
                $days ++;
                $time_to_convert = $time_to_convert - $FULL_DAY;
            }
    
            while($time_to_convert >= $FULL_HOUR) {
                $hours++;
                $time_to_convert = $time_to_convert - $FULL_HOUR;
            }
    
            while($time_to_convert >= $FULL_MINUTE) {
                $minutes++;
                $time_to_convert = $time_to_convert - $FULL_MINUTE;
            }
    
            $seconds = $time_to_convert; // remaining seconds
            $this->y = $years;
            $this->m = $months;
            $this->d = $days;
            $this->h = $hours;
            $this->i = $minutes;
            $this->s = $seconds;
        }
    }
    

J'espère que ça aide quelqu'un.

6
nembleton

J'essayais d'améliorer la réponse de Christopher Pickslay. 

J'ai créé cette fonction qui retourne un objet contenant la plupart des propriétés de l'objet DateInterval d'origine. 

Il n'y a pas de propriété "days", car il semble que ce soit un bogue sur mon serveur de test (il retourne toujours 6015). 

En outre, je suppose que chaque mois a 30 jours, ce qui est certainement pas précis, mais peut aider. 

function dateTimeDiff($date1, $date2) {

    $alt_diff = new stdClass();
    $alt_diff->y =  floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24*365));
    $alt_diff->m =  floor((floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365))/30);
    $alt_diff->d =  floor(floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365) - ($alt_diff->m * 30));
    $alt_diff->h =  floor( floor(abs($date1->format('U') - $date2->format('U')) / (60*60)) - ($alt_diff->y * 365*24) - ($alt_diff->m * 30 * 24 )  - ($alt_diff->d * 24) );
    $alt_diff->i = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60)) - ($alt_diff->y * 365*24*60) - ($alt_diff->m * 30 * 24 *60)  - ($alt_diff->d * 24 * 60) -  ($alt_diff->h * 60) );
    $alt_diff->s =  floor( floor(abs($date1->format('U') - $date2->format('U'))) - ($alt_diff->y * 365*24*60*60) - ($alt_diff->m * 30 * 24 *60*60)  - ($alt_diff->d * 24 * 60*60) -  ($alt_diff->h * 60*60) -  ($alt_diff->i * 60) );
    $alt_diff->invert =  (($date1->format('U') - $date2->format('U')) > 0)? 0 : 1 ;

    return $alt_diff;
}    
3
Luciano Santana

J'utilise ceci, semble fonctionner correctement - vous pouvez évidemment ajouter un deuxième paramètre pour le rendre plus flexible:

function GetDateDiffFromNow($originalDate) 
{
    $unixOriginalDate = strtotime($originalDate);
    $unixNowDate = strtotime('now');
    $difference = $unixNowDate - $unixOriginalDate ;
    $days = (int)($difference / 86400);
    $hours = (int)($difference / 3600);
    $minutes = (int)($difference / 60);
    $seconds = $difference;

    // now do what you want with this now and return ...
}
3
Dave

Oui, c'est embêtant que cette fonctionnalité n'ait pas été intégrée à PHP 5.2.

Je suppose que vous ne pouvez pas passer à la version 5.3? Vous devriez examiner; il y a très peu de raisons de ne pas mettre à jour; mais je suppose que vous ne pouvez pas pour une raison quelconque.

Premier conseil: si vous avez seulement besoin d'un diff de moins de 24 heures, vous pouvez simplement soustraire les deux horodatages et effectuer $time_diff = date('H:i:s',$subtracted_value);.

Si vous effectuez des différences de plus de 24 heures, mais que vous pouvez simplement renvoyer le nombre de jours avec le décalage horaire, vous pouvez développer la technique ci-dessus en effectuant un calcul de module sur la valeur soustraite, par rapport au nombre de secondes dans une journée (ie 24 * 60 * 60, soit 86400)

$subtracted_value = $date1 - $date2;
$days_diff = $subtracted_value % 86400;
$time_diff = date('H:i:s',$subtracted_value);

Si vous avez besoin de semaines, vous pouvez bien sûr faire $days_diff % 7.

Malheureusement, la technique manuelle tombe en panne après des semaines, car les mois et les années sont de longueur variable (techniquement, les jours le sont également, vu l'heure avancée), mais vous pouvez probablement l'ignorer, d'autant plus que vous ne passerez qu'une heure, le plus), mais j'espère que c'est assez bon pour vous aider à démarrer.

2
Spudley

Lisez les notes de contrib dans la page PHP date_diff http://us3.php.net/manual/fr/function.date-diff.php

2
ZCJ

Spudley était proche, mais vous devez utiliser gmdate not date.

Donc, cela fonctionne pendant 24 heures ou moins (si c'est une valeur positive au moins):

$difference = $date2->format('U') - $date1->format('U');
$time_diff = gmdate('H:i:s',$difference);
2
Mark

Veuillez noter que si votre objet DateTime a été créé à partir d'une chaîne de date sans aucune information de fuseau horaire (comme dans '2012-01-01 05:00:00' comme dans mysql), le réglage ultérieur du fuseau horaire avec des objets DateTimeZone via setTimeZone () ne modifiez pas l'horodatage interne des objets DateTime.

$localtime = new DateTime('2012-01-01 08:00:00+02:00'); // Europe/Copenhagen (+ daylight savings)
$localtime->setTimezone(new DateTimeZone('UTC')); // convert local time to utc

$utctime = new DateTime('2012-01-01 06:00:00'); // timezone assumed utc, but is in fact unknown
$utctime->setTimezone(new DateTimeZone('UTC')); // trying to rectify missing timezone which fails, because the internal timestamp isn't modified, although any other format than 'U' may indicate so
#$utctime = new DateTime('2012-01-01 06:00:00+00:00'); // timezone stated, this works

$diff = intval($localtime->format('U')) - intval($utctime->format('U'));
echo $diff; // expecting zero
0
andkrup

Voici la meilleure solution pour votre question.

<?php

/* Find difference between two dates in days. PHP 5.2.x.  */

$d1 = date('Y-m-d', strtotime('2013-06-13'));
$d2 = date("Y-m-d");
echo diff($d1, $d2);

function diff($date1, $date2) {
    $diff = abs(strtotime($date2) - strtotime($date1));
    $years = floor($diff / (365*60*60*24));
    $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
    $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24) / (60*60*24));
    return $days;
}
?>
0
Mohanraj

PHP a des méthodes pour travailler avec les timestamps Unix.

Comme d'autres l'ont fait remarquer, en travaillant avec des secondes depuis la date Unix, il est facile de calculer les temps.

La fonction strtotime () de PHP convertit une date en un horodatage:

$diff = round((strtotime($list['start']) - strtotime($list['finish'])) / 86400);

Si vous souhaitez calculer jusqu'à l'heure actuelle, time () fournit l'horodatage de "maintenant":

$diff = round((time() - strtotime($list['date'])) / 86400);

86400 est le nombre de secondes dans une journée.
Si vous souhaitez convertir en années, utilisez 31557000, soit presque exactement 365.24219 * 86400.

Un avantage supplémentaire ici est que strtotime peut prendre la date d'entrée dans presque n'importe quel format lisible par l'homme, il est donc très facile de travailler avec le code.

0
SamGoody