1

PHP プロジェクトの 2 つの日付の差を計算しようとしています。

例: 4 月 2 日と 6 月 1 日の違いは何ですか?

違いを計算する最初の方法
4 月 2 日から 5 月 2 日まで = 1 か月。5 月 2 日から 6 月 1 日まで = 30 日。=> 4 月 2 日から 6 月 1 日まで = 1 か月と 30 日

差額
を計算する 2 番目の方法 5 月を 1 か月と数えます。次に、4 月 2 日から 30 日までの日数 (28 日) と 6 月からの日数 (1 日) を足す => 1 か月と 29 日。

ほとんどの人がこの方法で計算していると思うので、最初の方法が正しいと思います。

最初は DateTime::diff() 関数を使用しようとしました

function dateDiff($date1, $date2 = false) {
if (!$date2)
    $date2 = date('Y-m-d');

$datetime1 = new DateTime($date1 , new DateTimeZone('EUROPE/Sofia'));
$datetime2 = new DateTime($date2 , new DateTimeZone('EUROPE/Sofia'));

$interval = $datetime1->diff($datetime2);

$y = $interval->format('%y');
$m = $interval->format('%m');
$d = $interval->format('%d');

return $y . " " . $m . " " . $d;

}

しかし、違いが正しく計算されていないことに気付きました。'2015-02-03' と '2015-04-02' の差は1 か月と 30 日(02-03 から 03-03 = 1 か月) である必要があります。その後、残りの日数を 04-02 までカウントします。 、これは 30 です)、 しかし diffはそれを1 か月と 27 日として計算しました (上で述べた 2 番目の方法で差を計算していると思います)。したがって、計算が間違っているか、2 番目の方法が正しい計算方法です。

しかし、この例を調べてみましょう: 2015-05-01 と 2015-03-31 (今回は遡ります)。diff は1 か月の差を返します。これは1 か月と 1 日である必要があると思います。

さらに、2015-05-01 と 2015-02-28 の差は2 か月と 1 日であるはずですが、diff 関数は2 か月と 3 日を返します。

では、2 つの日付の差を計算する正しい方法はどれですか? DateTime::diff() は正しく計算されていますか? そして、最初の方法で2つの日付の差を計算する方法はありますか.

4

3 に答える 3

0

これにより、差が正しく計算されます。

function monthDiff($m1, $m2) {
    if($m1 > $m2) {
        return 12 - $m1 + $m2;
    }
    return $m2 - $m1;
}

function yearDiff($y1, $y2) {
    return $y2 - $y1;
}


function checkLeapYear($year){
    $year = (int)$year;
    return ( ( ($year % 4 == 0 && ($year % 100) != 0 ) || ( ($year % 100) == 0 && ($year % 400) == 0 ) ) ? 1 : 0);
}


function dateDiff($date1, $date2 = false) {
    if (!$date2)
        $date2 = date('Y-m-d');

    $datetime1 = new DateTime($date1 , new DateTimeZone('EUROPE/Sofia'));
    $datetime2 = new DateTime($date2 , new DateTimeZone('EUROPE/Sofia'));

    if($datetime1 > $datetime2){ //always go from smaller to bigger date
        $temp = $datetime1;
        $datetime1 = $datetime2;
        $datetime2 = $temp; 
    }

    $d1 = (int)$datetime1->format('d');
    $d2 = (int)$datetime2->format('d');

    $m1 = (int)$datetime1->format('m');
    $m2 = (int)$datetime2->format('m');

    $y1 = (int)$datetime1->format('Y');
    $y2 = (int)$datetime2->format('Y');


    $leapYear = checkLeapYear($y1); 
    $daysInMonth1 = [1 => 31, 28 + $leapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // the number of days in the months

    $leapYear = checkLeapYear($y2);
    $daysInMonth2 = [1 => 31, 28 + $leapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];


    $monthCorrection = 0;


    if ($d1 < $d2) {
        $d = $d2 - $d1; 
    }

    if ($d1 > $d2){
        if ($daysInMonth2[$m2] >= $d1){ 
            $d = $daysInMonth1[$m1] - $d1 + $d2;;
        }
        else {
            $d = $daysInMonth1[$m1] - $d1 + $d2;
        }
        $monthCorrection = -1;
    }

    if ($d1 == $d2 ){
        $d = 0;
    }

    $m = monthDiff($m1, $m2) + $monthCorrection;

    $y = yearDiff($y1, $y2);
    if ($m1 > $m2){
        $y--;
    }

    return $y . " years " . $m . " months " . $d . " days";

}
于 2015-11-16T09:19:03.743 に答える
0

PHP にバグがありDateIntervalます。今のところ、 Momentライブラリなどの外部実装を使用してみるか、バグ ステータスに従って修正されるのを待つことができます。

于 2015-11-09T12:43:06.387 に答える
-2

ここに小さな例があります、それが役に立てば幸いです

$date1 = strtotime("2015-01-01"); //yyyy-mm-dd
$date2 = strtotime("2015-01-08");
$datediff = $date2 - $date1;
echo floor($datediff/(60*60*24));
于 2015-11-09T12:49:45.360 に答える