2015-09-09 1 views
2

Когда объект DateTime имеет дату «2012-01-30», мы имеем следующий объект:Фикс високосным ошибка при добавлении месяц PHP

object(DateTime)#1233 (3) { 
    ["date"]=> 
    string(19) "2012-01-30 00:00:00" 
    ["timezone_type"]=> 
    int(3) 
    ["timezone"]=> 
    string(9) "ETC/GMT+3" 
} 

Но, когда добавляется в месяц:

$date->add(new DateInterval('P1M')); 

Это приведет следующий объект:

object(DateTime)#1233 (3) { 
    ["date"]=> 
    string(19) "2012-03-01 00:00:00" 
    ["timezone_type"]=> 
    int(3) 
    ["timezone"]=> 
    string(9) "ETC/GMT+3" 
} 

необходимо добавить в месяц, так что дата будет отображаться должна быть '2012-02-28', поэтому февраль 2012 года, а не марш 2012 года.

Как я мог исправить это?

+0

Обратите внимание, что это «переполнение» или поведение «опрокидывание» является частью дизайна. См. [Описано в примере №3 в документах] (http://php.net/manual/en/datetime.add.php). Это распространено и на других языках, но ИМХО это плохой дизайн - по той причине, что вы проиллюстрировали. Кроме того, это всего лишь високосный год, когда в феврале 2012 года было 29 дней. Это все еще проблема для * любого * месяца * любого * года, когда количество дней в результирующем месяце меньше, чем часть дня даты начала. –

ответ

1

попробовать этот

function add($date_str, $months) 
{ 
    $date = new DateTime($date_str); 
    $start_day = $date->format('j'); 

    $date->modify("+{$months} month"); 
    $end_day = $date->format('j'); 

    if ($start_day != $end_day) 
     $date->modify('last day of last month'); 

    return $date; 
} 

$result = add('2011-01-31', 1); // 2011-02-28 
+0

Это хороший обходной путь, но я думаю, что, вероятно, есть способ, который не требует форматирования или разбора на естественном языке. –