web-dev-qa-db-ja.com

PHP 5.2の場合、DateTime :: diff()には何を使用できますか?

PHP 5.2のDateTime :: diff()に相当する関数はありますか?

私のローカルサーバーは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

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;
26
shin

Spudleyの答えは私にはうまくいきません。別の日付時刻から任意のDateTimeを引くと、私のシステムでは0になります。

DateTime :: formatを 'U'指定子(Unixエポックからの秒数)を使用して機能させることができました。

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

これは私の開発システム(5.3.4)と私の配備システム(5.2.11)の両方で機能します。

40

WordPressプラグインに(残念ながら)必要なだけです。これは私が関数を2回使用します:

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

それが誰かを助けることを願っています。

6
nembleton

クリストファー・ピックスレイの答えを改善しようとしていました。

元のDateIntervalオブジェクトからのプロパティのほとんどを返すオブジェクトを返すこの関数を作成しました。

テストサーバーでは some bug と思われるため、 "days"プロパティはありません(常に6015を返します)。

また、毎月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;
}    
3
Luciano Santana

私はこれを使用していますが、問題なく動作しているようです。明らかに、2つ目のパラメータを追加して、より柔軟にすることができます。

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

はい、その機能がPHP5.2に組み込まれなかったことは不愉快です。

5.3にアップグレードできないと思いますか?あなたはそれを調べるべきです。アップグレードしない理由はほとんどありません。でも理由が何であれあなたはできないと思います。

最初のヒント:24時間未満の差分のみが必要な場合は、2つのタイムスタンプを引くだけで、$time_diff = date('H:i:s',$subtracted_value);を実行できます。

24時間を超える差分を実行しているが、日数と時間の差を返すだけで問題ない場合は、上記の手法を拡張して、計算された値に対して、減算された値でモジュラス計算を実行できます。 1日の秒数(つまり、24 * 60 * 60、つまり86400)

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

数週間が必要な場合は、もちろんできます$days_diff % 7

残念ながら、手動の手法は数か月後に機能しなくなります。これは、月と年の長さが可変であるためです(技術的には、夏時間を考慮すれば、日もそうですが、特に、1時間しか外れないので、おそらく無視できます。ほとんど))、しかしうまくいけばそれはあなたが始めるのに十分良いことです。

2
Spudley

PHP date_diff page http://us3.php.net/manual/en/function.date-diff.php の投稿メモを読んでください

2
ZCJ

Spudleyは近くにありましたが、日付ではなくgmdateを使用する必要があります。

したがって、これは24時間以下で機能します(少なくとも正の値の場合):

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

DateTimeオブジェクトがタイムゾーン情報なしの日付文字列から作成された場合(mysqlのように「2012-01-01 05:00:00」のように)、後で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
0
andkrup

これがあなたの質問に最適なソリューションです。

<?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
Mohan

PHPには、Unixタイムスタンプを操作するためのメソッドがあります。

他の人が指摘しているように、Unixの日付から秒を使用することで、時間の計算が簡単になります。

PHPのstrtotime()は日付をタイムスタンプに変換します:

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

現在の時刻まで計算したい場合、time()は「今」のタイムスタンプを提供します。

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

86400は1日の秒数です。
年に変換する場合は、31557000を使用します。これは、ほぼ正確に365.24219 * 86400です。

ここでの追加の利点は、strtotimeがほとんどすべての人間が読める形式で入力日付を取得できるため、コード内での操作が非常に簡単です。

0
SamGoody