PHP DateTime :: изменить сложение и вычитание месяцев - PullRequest
89 голосов
/ 30 августа 2010

Я много работал с DateTime class и недавно столкнулся с ошибкой при добавлении месяцев.После небольшого исследования кажется, что это не ошибка, а работа по назначению.В соответствии с найденной документацией здесь :

Пример # 2 Осторожно при сложении или вычитании месяцев

<?php
$date = new DateTime('2000-12-31');

$date->modify('+1 month');
echo $date->format('Y-m-d') . "\n";

$date->modify('+1 month');
echo $date->format('Y-m-d') . "\n";
?>
The above example will output:
2001-01-31
2001-03-03

Кто-нибудь может объяснить, почему это не считается ошибкой?

Кроме того, есть ли у кого-нибудь изящные решения, чтобы исправить проблему и сделать так, чтобы +1 месяц работал как положено, а не как предполагалось?

Ответы [ 19 ]

0 голосов
/ 20 августа 2016
$ds = new DateTime();
$ds->modify('+1 month');
$ds->modify('first day of this month');
0 голосов
/ 09 февраля 2016

Мне нужно было получить дату «этот месяц в прошлом году», и это довольно неприятно, когда этот месяц - февраль високосного года. Тем не менее, я считаю, что это работает ...: / / Уловка, по-видимому, заключается в том, чтобы основывать ваши изменения на 1-й день месяца.

$this_month_last_year_end = new \DateTime();
$this_month_last_year_end->modify('first day of this month');
$this_month_last_year_end->modify('-1 year');
$this_month_last_year_end->modify('last day of this month');
$this_month_last_year_end->setTime(23, 59, 59);
0 голосов
/ 05 июня 2013
     $date = date('Y-m-d', strtotime("+1 month"));
     echo $date;
0 голосов
/ 13 мая 2014

Расширение для класса DateTime, которое решает проблему сложения или вычитания месяцев

https://gist.github.com/66Ton99/60571ee49bf1906aaa1c

0 голосов
/ 15 февраля 2015

вы можете сделать это просто с помощью date () и strtotime ().Например, чтобы добавить 1 месяц к текущей дате:

date ("Ymd", strtotime ("+ 1 month", time ()));

, если вы хотите использовать datetimeКласс это тоже хорошо, но это так же просто. подробнее здесь

0 голосов
/ 02 февраля 2013

Если вы просто хотите избежать пропуска месяца, вы можете выполнить что-то вроде этого, чтобы получить дату и запустить цикл в следующем месяце, сократив дату на единицу и перепроверив до действительной даты, где $ начальная_калькуляция является допустимой строкой дляstrtotime (т. е. mysql datetime или "сейчас").Это находит самый конец месяца с 1 минуты до полуночи вместо того, чтобы пропустить месяц.

    $start_dt = $starting_calculated;

    $next_month = date("m",strtotime("+1 month",strtotime($start_dt)));
    $next_month_year = date("Y",strtotime("+1 month",strtotime($start_dt)));

    $date_of_month = date("d",$starting_calculated);

    if($date_of_month>28){
        $check_date = false;
        while(!$check_date){
            $check_date = checkdate($next_month,$date_of_month,$next_month_year);
            $date_of_month--;
        }
        $date_of_month++;
        $next_d = $date_of_month;
    }else{
        $next_d = "d";
    }
    $end_dt = date("Y-m-$next_d 23:59:59",strtotime("+1 month"));
0 голосов
/ 09 августа 2017
$month = 1; $year = 2017;
echo date('n', mktime(0, 0, 0, $month + 2, -1, $year));

выдаст 2 (февраль).будет работать и в другие месяцы.

0 голосов
/ 07 января 2019
$current_date = new DateTime('now');
$after_3_months = $current_date->add(\DateInterval::createFromDateString('+3 months'));

Для дней:

$after_3_days = $current_date->add(\DateInterval::createFromDateString('+3 days'));

Важно:

Метод add() класса DateTime изменяет значение объекта, поэтому после вызова add() для объекта DateTime он возвращает новый объект даты, а также изменяет сам объект.

0 голосов
/ 29 января 2015

При использовании strtotime() просто используйте $date = strtotime('first day of +1 month');

...