Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: Adding months to a date, while not exceeding the last day of the month

Tags:

date

php

Looking to create a function that will do this in PHP.

I need to add a number of months to a date, but not exceed the last day of the month in doing so.

For example:

Add 1 month to January (1-28th), 2011, should produce February (1-28th), 2011. Add 1 month to January 30th, 2011, should produce February 28th, 2011. Add 3 months to January 31st, 2011, should produce April 30th, 2011. Add 13 months to January 30th, 2011, should produce February 29th, 2012. Add 1 month to October 31st, 2011, should produce November 30th, 2011. 

If I use date addition in PHP, I get overruns:

Adding 1 month to January 30th, 2011, results in March 2nd, 2011. 

My specification doesn't allow me to overrun into a new month.

What's the easiest method to accomplish this?

like image 974
Geoff Maddock Avatar asked Apr 22 '11 21:04

Geoff Maddock


People also ask

How can get first and last day of month in php?

php $dt = "2008-02-23"; echo 'First day : '. date("Y-m-01", strtotime($dt)). ' - Last day : '. date("Y-m-t", strtotime($dt)); ?>

How do I get the last day of the current month in php?

$date = strtotime ( $datestring ); // Last date of current month. $day = date ( "l" , $lastdate );


2 Answers

You can compare the day of the month before and after you add 1 month. If it's not the same, you exceeded the next month.

function add($date_str, $months) {     $date = new DateTime($date_str);      // We extract the day of the month as $start_day     $start_day = $date->format('j');      // We add 1 month to the given date     $date->modify("+{$months} month");      // We extract the day of the month again so we can compare     $end_day = $date->format('j');      if ($start_day != $end_day)     {         // The day of the month isn't the same anymore, so we correct the date         $date->modify('last day of last month');     }      return $date; }  $result = add('2011-01-28', 1);   // 2011-02-28 $result = add('2011-01-31', 3);   // 2011-04-30 $result = add('2011-01-30', 13);  // 2012-02-29 $result = add('2011-10-31', 1);   // 2011-11-30 $result = add('2011-12-30', 1);   // 2011-02-28 
like image 176
Crend King Avatar answered Oct 13 '22 10:10

Crend King


this seems to work for me and gives yor desired result:

<?php $date = "2011-01-30";  list($year,$month,$day) = explode("-",$date);  // add month here $month++; // to avoid a month-wrap, set the day to the number of days of the new month if it's too high $day = min($day,date("t",strtotime($year."-".$month."-01")));   $date = $year."-".$month."-".$day;  // 2011-02-28 echo $date; ?> 

EDIT:
after reading Crend Kings comemnt, i think we need more information here. whats the desired result in the following cases:

2011-01-30 > 2011-02-28  2011-01-28 > 2011-02-28 or 2011-02-26 ? 2011-02-01 > 2011-03-01 or 2011-03-03 ? 

in words: should the method add the number of days of the next month, wich is what Crend King does and what gives results like 2011-02-26 and 2011-03-03 (wich doesn't seem like the desired results to me) or should this add one month and leave the day as is, instead of a day thats "too high" like my code does? i'm confused...

like image 33
oezi Avatar answered Oct 13 '22 12:10

oezi