Я пытаюсь вычислить разницу между двумя датами для проекта 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()? И есть ли способ вычислить разницу между двумя датами по первому методу.
Это должно правильно рассчитать разницу.
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";
}
У Php есть ошибка с DateInterval
. На данный момент вы можете попробовать использовать внешние реализации, такие как Moment library, или следить за статусом ошибки и ждать, когда она будет исправлена.
Вот небольшой пример, надеюсь, что это поможет
$date1 = strtotime("2015-01-01"); //yyyy-mm-dd
$date2 = strtotime("2015-01-08");
$datediff = $date2 - $date1;
echo floor($datediff/(60*60*24));