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