strtotime ('- 1 месяц') возвращает неправильную дату, если месяц имеет 31 день - PullRequest
2 голосов
/ 01 мая 2020

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

Это пример моего кода:

// Dates in TimeStamp
$ts_now =  strtotime('now');
$ts_month1 = strtotime("-1 month", $ts_now);
$ts_month2 = strtotime("-2 month", $ts_now);
$ts_month3 = strtotime("-3 month", $ts_now);

// Dates Formated
$date_now = date('Y-m-d', $ts_now);
$date_month1 = date('Y-m-d', $ts_month1);
$date_month2 = date('Y-m-d', $ts_month2);
$date_month3 = date('Y-m-d', $ts_month3);

//Output
echo $date_now;    //2020-04-30
echo $date_month1; //2020-03-30
echo $date_month2; //2020-03-01
echo $date_month3; //2020-01-30

Проблема в том, что $date_month2 представляет февраль, выходное значение равно 2020-03-01 вместо 2020-02-29 , и я предполагаю, что проблема произойдет в месяцы, у которых есть 30 дней, когда у текущей даты есть 31 день.

Что лучший способ решить это?

1 Ответ

2 голосов
/ 01 мая 2020

Как вы можете видеть, работа с концом месяца может быть проблематичной c из-за того, как PHP работает с датами. Лучше всего go вернуться к началу месяца, выполнить математику даты (т. Е. go назад во времени), а затем go до желаемой даты. Таким образом, вы можете проверить, больше ли текущий день, чем количество дней в месяце. Если это так, используйте вместо этого последний день месяца.

function getMonthsAgo(int $n): string {
    $date = new DateTime();
    $day  = $date->format('j');
    $date->modify('first day of this month')->modify('-' . $n . ' months');
    if ($day > $date->format('t')) {
        $day = $date->format('t');
    }
    $date->setDate($date->format('Y'), $date->format('m'), $day);
    return $date->format('Y-m-d');
}

// Dates Formated
$date_now = date('Y-m-d');
$date_month1 = getMonthsAgo(1);
$date_month2 = getMonthsAgo(2);
$date_month3 = getMonthsAgo(3);

//Output
echo $date_now;
echo $date_month1;
echo $date_month2;
echo $date_month3;

Вывод:

2020-04-30
2020-03-30
2020-02-29
2020-01-30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...