Как правильно рассчитать разницу между 2 датами php

1

Я пытаюсь вычислить разницу между двумя датами для проекта php.

Например: в чем разница между 2 апреля и 1 июня?

Первый метод вычисления разности
Со 2 апреля до 2-го мая = 1 месяц. С 2 мая по 1 июня = 30 дней. => 2 апреля - 1 июня = 1 месяц и 30 дней

Второй метод расчета разницы
Мы можем рассчитывать на 1 месяц. Затем добавьте дни со 2-го по 30-е апреля (28 дней) и дни с июня (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), НО ДИФ рассчитал его как 1 месяц и 27 дней (я думаю, он вычисляет разницу по второму методу, который я изложил выше). Поэтому он либо вычисляет неправильно, либо второй метод является правильным способом вычисления.

НО Давайте рассмотрим этот пример: 2015-05-01 и 2015-03-31 (на этот раз мы будем отставать). Дифф возвращает разницу в 1 месяц, где я думаю, что это должно быть 1 месяц и 1 день.

Кроме того, разница между 2015-05-01 и 2015-02-28 должна составлять 2 месяца и 1 день, но функция diff возвращает 2 месяца и 3 дня.

Итак, что является правильным способом расчета разницы между двумя датами? Правильно ли вычисляется DateTime :: diff()? И есть ли способ вычислить разницу между двумя датами по первому методу.

Теги:
datetime
date
date-difference

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

}
0

У Php есть ошибка с DateInterval. На данный момент вы можете попробовать использовать внешние реализации, такие как Moment library, или следить за статусом ошибки и ждать, когда она будет исправлена.

-1

Вот небольшой пример, надеюсь, что это поможет

$date1 = strtotime("2015-01-01"); //yyyy-mm-dd
$date2 = strtotime("2015-01-08");
$datediff = $date2 - $date1;
echo floor($datediff/(60*60*24));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню