What can use for DateTime::diff() for PHP 5.2?

你离开我真会死。 提交于 2019-12-17 04:32:12

问题


Is there any function equivalent to DateTime::diff() in PHP 5.2?

My local server is PHP 5.3 and using DateTime::diff(). then I found that my live site uses PHP 5.2 and gives an error.

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

The PHP code:

 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;

回答1:


Spudley's answer doesn't work for me--subtracting any DateTime from another gives 0 on my system.

I was able to get it to work by using DateTime::format with the 'U' specifier (seconds since Unix epoch):

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

This works on both my dev system (5.3.4) and my deployment system (5.2.11).




回答2:


I just needed that ( unfortunately ) for a WordPress plugin. This I use the function in 2 times:

  1. In my class calling ->diff() ( my class extends DateTime, so $this is the reference DateTime )

    function diff ($secondDate){
        $firstDateTimeStamp = $this->format("U");
        $secondDateTimeStamp = $secondDate->format("U");
        $rv = ($secondDateTimeStamp - $firstDateTimeStamp);
        $di = new DateInterval($rv);
        return $di;
    }
    
  2. Then I recreated a fake DateInterval class ( because DateInterval is only valid in PHP >= 5.3 ) as follows:

    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;
        }
    }
    

Hope that helps somebody.




回答3:


I use this, seems to work alright - obviously you can add a second parameter to make it more 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 ...
}



回答4:


I was trying to improve Christopher Pickslay's answer.

I made this function that returns and object with most of the properties from the original DateInterval object.

There is no "days" property, because it seems to be some bug in my test server (it always return 6015) .

Also, I am assuming every month has 30 days, which is definitely not precise, but may help.

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;
}    



回答5:


Yes, it's annoying that feature didn't make it into PHP5.2.

I'll assume you can't upgrade to 5.3? You should look into it; there's very little reason not to upgrade; but I'll assume you can't for whatever the reason.

First tip: If you only need a diff of less than 24hours, you can simply subtract the two time stamps, and do $time_diff = date('H:i:s',$subtracted_value);

If you're doing more than 24 hour diffs, but you're okay with just returning the number of days along with the time difference, you can expand on the above technique by doing a modulus calculation on the subtrated value, against the number of seconds in a day (ie 24*60*60, which is 86400)

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

If you need weeks, you can of course do $days_diff % 7.

Unfortunately, the manual technique breaks down after weeks, because months and years are variable in length (technically days are too, given daylight saving, but you can probably ignore that, especially as you're only ever going to be one hour out, at the most), but hopefully that's good enough to get you started.




回答6:


Read the contrib notes in the PHP date_diff page http://us3.php.net/manual/en/function.date-diff.php




回答7:


Spudley was close, but you need to use gmdate not date.

So this works for 24 hours or less (if it's a positive value at least):

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



回答8:


PHP has methods for working with Unix timestamps.

As has been noted by others, by working with seconds since the Unix date, it is easy to calculate times.

PHP's strtotime() converts a date to a timestamp:

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

If you wish to calculate till the current time, time() provides the timestamp of "now":

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

86400 is the number of seconds in a day.
If you wish to convert to years use 31557000, which is almost exactly 365.24219 * 86400.

An added advantage here is that strtotime can take the input date in almost any human readable format, so it is very easy to work with within the code.




回答9:


Please observe that if your DateTime object was created from a date string without any timezone information (as in '2012-01-01 05:00:00' like from mysql), then setting the timezone later with DateTimeZone objects via setTimeZone() does not change the DateTime objects internal timestamp.

$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



回答10:


Here is the best solution for your 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;
}
?>


来源:https://stackoverflow.com/questions/4033224/what-can-use-for-datetimediff-for-php-5-2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!