PHP разница даты и времени в месяцах возвращает неверные значения, неправильную php конфигурацию или ошибку - PullRequest
1 голос
/ 04 мая 2020

Поэтому я использую в своем сценарии метод datetime и diff для расчета разницы по месяцам, и я создаю тестовый сценарий, чтобы показать вам, в чем заключается моя проблема.

Запуск на моем сервере (удаленный linux и локальный windows дома, часовые пояса Европа / Варшава):

echo "StartDate\tEndDate\tMonthNum\tDifference\n";
for($i = 1; $i <= 12; $i++){
        $filters['date_from'] = "2020-$i-01";
        $filters['date_to'] = date("Y-m-t", strtotime("2020-$i-01"));
        $datetime1 = new DateTime($filters['date_from']);
        $datetime2 = new DateTime($filters['date_to']);
        $difference = $datetime1->diff($datetime2);
        $end = $difference->m;
            echo "{$filters['date_from']}\t{$filters['date_to']}\t" . $i . "\t$end\n";
}

и результат с PHP 7.1.29 и PHP 7.4.1:

StartDate       EndDate MonthNum        Difference
2020-1-01       2020-01-31      1       0
2020-2-01       2020-02-29      2       0
2020-3-01       2020-03-31      3       1
2020-4-01       2020-04-30      4       0
2020-5-01       2020-05-31      5       1
2020-6-01       2020-06-30      6       0
2020-7-01       2020-07-31      7       1
2020-8-01       2020-08-31      8       0
2020-9-01       2020-09-30      9       0
2020-10-01      2020-10-31      10      1
2020-11-01      2020-11-30      11      0
2020-12-01      2020-12-31      12      1

так, как вы видите diff показывая разницу в 0 или 1 месяц, 1, если в месяце более 30 дней, и 0, если меньше.

Итак, я проверил этот код на http://sandbox.onlinephpfunctions.com/, и результат отличается:

StartDate   EndDate MonthNum    Difference
2020-1-01   2020-01-31  1   0
2020-2-01   2020-02-29  2   0
2020-3-01   2020-03-31  3   0
2020-4-01   2020-04-30  4   0
2020-5-01   2020-05-31  5   0
2020-6-01   2020-06-30  6   0
2020-7-01   2020-07-31  7   0
2020-8-01   2020-08-31  8   0
2020-9-01   2020-09-30  9   0
2020-10-01  2020-10-31  10  0
2020-11-01  2020-11-30  11  0
2020-12-01  2020-12-31  12  0

Все месяцы имеют разницу в 0 месяцев, поэтому он работает хорошо, может быть, кто-то знает, в чем может быть проблема с моим сервером?

1 Ответ

1 голос
/ 04 мая 2020

Да, это ошибка. Разница от первого дня месяца до последнего дня месяца (00:00) всегда должна возвращать 0 месяцев, потому что последний день отсутствует. 1 месяц - с первого дня месяца (00:00) до первого дня следующего месяца в 00:00. Ошибка вызвана неправильным смещением часового пояса на UT C. Месяцы рассчитываются правильно, если часовой пояс UT C используется в качестве временного решения.

$tz = new dateTimeZone('UTC');
for($i = 1; $i <= 12; $i++){
  $n = $i+1;
  $dateFrom = "2020-$i-01";
  $dateTo = $n == 13 ? "2021-01-01" : "2020-$n-01";
  $diff = date_create($dateFrom,$tz)->diff(date_create($dateTo,$tz));
  echo $dateFrom." to ".$dateTo." = ".$diff->m. " month or ".$diff->days." days<br>\n";
}

Вывод:

2020-1-01 to 2020-2-01 = 1 month or 31 days
2020-2-01 to 2020-3-01 = 1 month or 29 days
2020-3-01 to 2020-4-01 = 1 month or 31 days
2020-4-01 to 2020-5-01 = 1 month or 30 days
2020-5-01 to 2020-6-01 = 1 month or 31 days
2020-6-01 to 2020-7-01 = 1 month or 30 days
2020-7-01 to 2020-8-01 = 1 month or 31 days
2020-8-01 to 2020-9-01 = 1 month or 31 days
2020-9-01 to 2020-10-01 = 1 month or 30 days
2020-10-01 to 2020-11-01 = 1 month or 31 days
2020-11-01 to 2020-12-01 = 1 month or 30 days
2020-12-01 to 2021-01-01 = 1 month or 31 days
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...