什么可以用于 PHP 5.2 的 DateTime::diff() ?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4033224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:47:15  来源:igfitidea点击:

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

phpphp-5.2

提问by shin

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

PHP 5.2 中是否有与 DateTime::diff() 等效的函数?

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.

我的本地服务器是 PHP 5.3 并使用 DateTime::diff()。然后我发现我的实时站点使用 PHP 5.2 并出现错误。

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:

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;

回答by Christopher Pickslay

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

Spudley 的回答对我不起作用——从另一个 DateTime 中减去任何 DateTime 在我的系统上给出 0。

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

我能够通过使用 DateTime::format 和 'U' 说明符(自 Unix 纪元以来的秒数)来让它工作:

$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).

这适用于我的开发系统 (5.3.4) 和我的部署系统 (5.2.11)。

回答by nembleton

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

我只是需要(不幸的是)用于 WordPress 插件。这我使用该功能2次:

  1. In my class calling ->diff()( my class extends DateTime, so $thisis 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;
        }
    }
    
  1. 在我的课程中调用->diff()(我的课程扩展了DateTime,所以$this是参考DateTime

    function diff ($secondDate){
        $firstDateTimeStamp = $this->format("U");
        $secondDateTimeStamp = $secondDate->format("U");
        $rv = ($secondDateTimeStamp - $firstDateTimeStamp);
        $di = new DateInterval($rv);
        return $di;
    }
    
  2. 然后我重新创建了一个假的 DateInterval 类(因为 DateInterval 仅在 PHP >= 5.3 中有效)如下:

    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.

希望能帮助某人。

回答by Dave

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

回答by Luciano Santana

I was trying to improve Christopher Pickslay's answer.

我试图改进 Christopher Pickslay 的回答。

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

我制作了这个函数,它返回原始DateInterval对象的大部分属性。

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

没有“days”属性,因为它似乎是我的测试服务器中的一些错误(它总是返回 6015)。

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

另外,我假设每个月都有 30 天,这绝对不准确,但可能会有所帮助。

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

回答by Spudley

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

是的,令人讨厌的是,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.

我假设你不能升级到 5.3?你应该调查一下;几乎没有理由不升级;但我会假设你不能因为任何原因。

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

第一个提示:如果您只需要小于 24 小时的差异,您可以简单地减去两个时间戳,然后执行 $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)

如果你做的差异超过 24 小时,但你可以只返回天数和时差,你可以通过对减去的值进行模数计算来扩展上述技术,相对于数量一天中的秒数(即 24*60*60,即 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.

如果您需要数周,您当然可以这样做$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.

不幸的是,手动技术在几周后就会失效,因为月和年的长度是可变的(技术上天也是如此,考虑到夏令时,但您可能可以忽略这一点,特别是因为您只会外出一小时,在大多数),但希望这足以让您入门。

回答by ZCJ

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

阅读 PHP date_diff 页面http://us3.php.net/manual/en/function.date-diff.php中的贡献注释

回答by Mark

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

Spudley 很接近,但您需要使用 gmdate 而不是 date。

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

所以这适用于 24 小时或更短的时间(如果它至少是一个正值):

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

回答by SamGoody

PHP has methods for working with Unix timestamps.

PHP 有处理 Unix 时间戳的方法。

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

正如其他人所指出的,通过使用自 Unix 日期以来的秒数,很容易计算时间。

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

PHP 的 strtotime() 将日期转换为时间戳:

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

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

如果你想计算到当前时间,time() 提供“现在”的时间戳:

$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.

86400 是一天中的秒数。
如果您希望转换为年份,请使用 31557000,这几乎就是 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.

这里的另一个优势是 strtotime 可以采用几乎任何人类可读格式的输入日期,因此在代码中使用它非常容易。

回答by andkrup

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.

请注意,如果您的 DateTime 对象是从没有任何时区信息的日期字符串创建的(如 '2012-01-01 05:00:00' 就像来自 mysql),那么稍后通过 setTimeZone() 使用 DateTimeZone 对象设置时区不更改 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

回答by Mohan

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