Как добавить 1 месяц на дату без пропуска, т.е. февраль
Возможный дубликат:
PHP DateTime:: изменить сложение и вычитание месяцев
У меня есть дата начала (например, 2011-01-30) и хочу добавить 1 месяц.
Проблема в том, чтобы определить, что такое месяц. Так что, если я использую следующий код:
$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57');
$d1->add(new DateInterval('P1M'));
echo $d1->format('Y-m-d H:i:s');
Я получаю следующий результат: 2011-03-02 15:57:57
Проблема в том, что мне нужно использовать следующие правила:
- Если я добавлю 1 месяц, он просто добавит 1 к части месяца и оставит часть дня (2011-01-15 станет 2011-02-15)
- Если день не существует в том месяце, который мы закончим, мы берем последний существующий день (2011-01-30 станет 2011-02-28)
Есть ли в php общая функция, которая может это сделать, или я должен сам ее кодировать? Может быть, я просто пропущу параметр или что-то!?
3 ответа
Кажется, для него нет готовой функции, поэтому я написал это сам. Это должно решить мою проблему. В любом случае, спасибо за ваши ответы и комментарии. Если вы найдете какие-либо ошибки, пожалуйста, укажите в комментариях.
Эта функция вычисляет месяц и год, в котором я закончу после добавления некоторого месяца. Затем он проверяет правильность даты. Если нет, у нас есть случай, когда день не находится в целевом месяце, поэтому мы берем последний день в этом месяце. Протестировано с PHP 5.3.10.
<?php
$monthToAdd = 1;
$d1 = DateTime::createFromFormat('Y-m-d 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('Y-n-j', $year.'-'.$month.'-1');
$d2->modify('last day of');
}else {
$d2 = DateTime::createFromFormat('Y-n-d', $year.'-'.$month.'-'.$day);
}
$d2->setTime($d1->format('H'), $d1->format('i'), $d1->format('s'));
echo $d2->format('Y-m-d H:i:s');
У вас есть несколько альтернатив, кроме 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 ( 'Y-m-j' , $newdate );
echo $newdate;
...
// Subtracting months from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 month' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );
echo $newdate;
Вот несколько ссылок для DateInterval
:
Q: Как именно вы определяете "месяц"?
DeF#1): "месяц" - это "месяц" - независимо от #/ дней
DeF#2): "месяц" - это 30 дней (например)
DeF#3): "месяц" - это число #/ дней между 1-м понедельником последующих месяцев
и т. д.
Q: Каково ваше "определение"?
Хорошо, насколько я могу судить, вы все еще не четко определили, что вы подразумеваете под "месяцем".
Но вот еще одна функция, которая может помочь:
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('Y-m-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;
}