Как добавить 1 месяц на дату без пропусков, т.е. февраль

Возможный дубликат:
PHP DateTime :: изменить время добавления и вычитания

У меня есть дата начала (т.е. 2011-01-30) и вы хотите добавить 1 месяц.

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

$d1 = DateTime::createFromFormat('Ymd H:i:s', '2011-01-30 15:57:57'); $d1->add(new DateInterval('P1M')); echo $d1->format('Ymd H:i:s'); 

Я получаю следующий результат: 2011-03-02 15:57:57

Проблема в том, что мне нужно, чтобы она использовала следующие правила:

  • Если я добавлю 1 месяц, он просто добавит 1 часть месяца и покинет дневную часть (2011-01-15 станет 2011-02-15)
  • Если день не будет в конце месяца, мы закончим, мы проведем последний существующий день (2011-01-30 станет 2011-02-28)

Есть ли общая функция в php, которая может это сделать, или я должен сам ее кодировать? Может быть, я просто пропускаю параметр или что-то в этом роде?

У вас есть несколько альтернатив помимо DateInterval.

Вот примеры, которые используют strtotime() :

http://www.brightcherry.co.uk/scribbles/php-adding-and-subtracting-dates/

 // Subtracting days from a date $date = "1998-08-14"; $newdate = strtotime ( '-3 day' , strtotime ( $date ) ) ; $newdate = date ( 'Ymj' , $newdate ); echo $newdate; 

 // Subtracting months from a date $date = "1998-08-14"; $newdate = strtotime ( '-3 month' , strtotime ( $date ) ) ; $newdate = date ( 'Ymj' , $newdate ); echo $newdate; 

Вот некоторые ссылки для DateInterval :

Q: Как именно вы определяете «месяц»?

Def # 1): «месяц» – «месяц» – независимо от # / дня

Def # 2): «месяц» составляет 30 дней (например)

Def # 3): «месяц» – это # ​​/ дней между 1-м понедельником последующих месяцев

и т.д.

В: Каково ваше «определение»?

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

Эта функция вычисляет месяц и год, в которые я закончу, после добавления месяца. Затем он проверяет правильность даты. Если нет, мы имеем дело, что день не в целевом месяце, поэтому мы берем последний день месяца. Протестировано с помощью PHP 5.3.10.

 <?php $monthToAdd = 1; $d1 = DateTime::createFromFormat('Ymd H:i:s', '2011-01-30 15:57:57'); $year = $d1->format('Y'); $month = $d1->format('n'); $day = $d1->format('d'); $year += floor($monthToAdd/12); $monthToAdd = $monthToAdd%12; $month += $monthToAdd; if($month > 12) { $year ++; $month = $month % 12; if($month === 0) $month = 12; } if(!checkdate($month, $day, $year)) { $d2 = DateTime::createFromFormat('Yn-j', $year.'-'.$month.'-1'); $d2->modify('last day of'); }else { $d2 = DateTime::createFromFormat('Yn-d', $year.'-'.$month.'-'.$day); } $d2->setTime($d1->format('H'), $d1->format('i'), $d1->format('s')); echo $d2->format('Ymd H:i:s'); 

ОК – насколько я могу судить, вы все еще не определили, что вы подразумеваете под «месяцем».

Но вот еще одна функция, которая может помочь:

http://php.net/manual/en/function.getdate.php

 /* Function to find the first and last day of the month from the given date. * * Author Binu v Pillai binupillai2003@yahoo.com * @Param String yyyy-mm-dd * */ function findFirstAndLastDay($anyDate) { //$anyDate = '2009-08-25'; // date format should be yyyy-mm-dd list($yr,$mn,$dt) = split('-',$anyDate); // separate year, month and date $timeStamp = mktime(0,0,0,$mn,1,$yr); //Create time stamp of the first day from the give date. $firstDay = date('D',$timeStamp); //get first day of the given month list($y,$m,$t) = split('-',date('Ym-t',$timeStamp)); //Find the last date of the month and separating it $lastDayTimeStamp = mktime(0,0,0,$m,$t,$y);//create time stamp of the last date of the give month $lastDay = date('D',$lastDayTimeStamp);// Find last day of the month $arrDay = array("$firstDay","$lastDay"); // return the result in an array format. return $arrDay; }