Что может пойти не так при добавлении месяцев с DateInterval и DateTime :: add? - PullRequest
4 голосов
/ 14 февраля 2012

Мне не удалось найти правильное решение этой проблемы. Как вы видите в Примере № 3 в документации PHP, они утверждают, что нужно помнить при добавлении месяцев с использованием DateInterval в DateTime :: add.

На самом деле нет никакого объяснения, почему поведение метода таково и что я могу сделать, чтобы избежать этого, что я считаю ошибкой с первого взгляда.

Кто-нибудь имеет представление об этом?

Ответы [ 2 ]

7 голосов
/ 14 февраля 2012

Проблема в том, что в каждом месяце может быть разное количество дней. Вопрос в том, что вы делаете, когда хотите увеличить дату на 1 месяц. Согласно документации PHP, если вы используете 31 января (или 30 января) и добавляете 1 месяц, каково ожидаемое поведение?

В феврале всего 29 дней. Вы хотите установить последний день месяца? Как правило, безопаснее увеличиваться на определенное количество дней, если это то, что вы ищете, или статическую дату, основанную на текущей дате. Не зная, чего вы пытаетесь достичь, увеличивая свой месяц, сложно сказать, как следить за ошибкой.

EDIT:
Как кто-то упоминает в аналогичном посте, прокомментированном Майком Б выше, вы, вероятно, захотите сделать что-то, где вы (в псевдокоде):

 1) Use cal_days_in_month() for the next month and save that number to a variable x
 2) If x >= current billing DOB, increment and be done
 3) DateTime::modify('last day')  (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)

Стоит отметить, что если вы используете здесь переменную в качестве нового значения выставления счета, вы уничтожите свое первоначальное значение. Я бы сохранил дополнительное значение БД, которое является «первой датой выставления счета» или просто «billing_day_of_month» или что-то в этом роде, и использую это для определения дня месяца, на который вы должны смотреть

0 голосов
/ 30 ноября 2016

Если ваша цель состоит в строгом увеличении на удобные для пользователя месяцы (таким образом, 3 месяца с 21 января должны быть 21 апреля), за исключением того, что более короткие месяцы членства сокращаются (таким образом, 1 месяц с 31 января - 28 февраля / 29), тогда вам нужно вернуться на несколько дней назад, если вы перешли на следующий месяц:

function addMonths($date,$months) {
  $orig_day = $date->format("d");
  $date->modify("+".$months." months");
  while ($date->format("d")<$orig_day && $date->format("d")<5)
    $date->modify("-1 day");
}

$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...