0

2While trying to get the next month by adding the +1 month in strtotime function as well DateTime class, its not giving right answer when start date time is 31 January 2011.

<?php

$StartDateline = new DateTime("31 January 2011");

echo date('Y-m-d', $StartDateline->getTimestamp());
echo "<br>";
$EndDateline = $StartDateline->add(new DateInterval("P1M"));//strtotime("+1 month", $startDateline);

echo date('Y-m-d', $EndDateline->getTimestamp());

echo "<br>";

?>

Output is :

2011-01-31
2011-03-03

Expected result should be following or how should I get the following out put :

2011-01-31
2011-02-28

Thanks

krishna Prasad
  • 3,541
  • 1
  • 34
  • 44

4 Answers4

0

instead of specifying month specify date.

new DateInterval("P#D")// # no. of days.

or you can use modify.see here:http://php.net/manual/en/datetime.modify.php

Suchit kumar
  • 11,809
  • 3
  • 22
  • 44
0

This works:

<?php
    $StartDateline = new DateTime("31 January 2011");
    echo date('Y-m-d', $StartDateline->getTimestamp());
    echo "<br>";

    $test = $StartDateline->modify('last day of next month');
    echo date('Y-m-d', $test->getTimestamp());
    echo "<br>";
?>

result:

2011-01-31
2011-02-28

Here's a similar answer that exaplains why your way doesn't give the wanted output.

PHP docs on DateTime::modify method

edit: I understand now that you don't need the last day of next month, but the same day of next month. I found this code working:

function addMonthsToTime($numMonths = 1, $timeStamp = null){
    $timeStamp === null and $timeStamp = time();//Default to the present
    $newMonthNumDays =  date('d',strtotime('last day of '.$numMonths.' months', $timeStamp));//Number of days in the new month
    $currentDayOfMonth = date('d',$timeStamp);

    if($currentDayOfMonth > $newMonthNumDays){
      $newTimeStamp = strtotime('-'.($currentDayOfMonth - $newMonthNumDays).' days '.$numMonths.' months', $timeStamp);
    } else {
    $newTimeStamp = strtotime($numMonths.' months', $timeStamp);
    }

    return $newTimeStamp;
}

$timestamp = strtotime('2011-01-01');
echo date('m/d/Y', addMonthsToTime(1, $timestamp));
//02/01/2011

$timestamp = strtotime('2011-01-31');
echo date('m/d/Y', addMonthsToTime(1, $timestamp));
//02/28/2011

taken from this comment section on PHP's Relative Formats doc page.

Community
  • 1
  • 1
Nitsan Baleli
  • 5,393
  • 3
  • 30
  • 52
0

The current behavior of PHP DateTime is not wrong. What's really happening is

  • +1 month increases the month number (originally 1) by one. This makes the date 2011-03-03.
  • The second month (February) only has 28 days in 2011, so PHP auto-corrects this by just continuing to count days from February 1st. You then end up at March 3rd. January 31 + 31 days (1 month) = March 3 ( since there are only 28 days in february)

    See @shamittomar

To get the expected answer you should use the number of days

So just replace P1M with P28D to get desired result

$EndDateline = $StartDateline->add(new DateInterval("P28D"));

See DEMO

Community
  • 1
  • 1
John Robertson
  • 1,486
  • 13
  • 16
  • Since I want to increase a month in general, I don't know the date is 31 Jan or 30 Jan. or 1 Jan 2011. I just want to increase one month e.g : * 1 Jan 2011 should goes to 1 Feb 2011, * 30 or 31 Jan 2011 both should goes 28 Feb 2011 and so on. I want it is general. – krishna Prasad Sep 16 '14 at 08:07
  • @krishna you can do conditional statements with that one – John Robertson Sep 16 '14 at 08:13
  • Okay, Is it not possible through `Datetime` methods or `strtotime` function ?? – krishna Prasad Sep 16 '14 at 08:15
  • @krishna You can use P1M but there's a catch when february comes. That's why it is up to you to consider that and in the manual http://php.net/manual/en/datetime.add.php example three it says Beware when adding months. So use conditional statements to check the month. Check http://stackoverflow.com/questions/3602405/php-datetimemodify-adding-and-subtracting-months or study $d->modify( 'first day of next month' ) – John Robertson Sep 16 '14 at 08:25
0

John Robertson already explained why you get the result you get. The output is correct, because when you add +1 month to 31.1. it will become 31.2. which is 3 days more than 28.2., so correct results is 3.3..

For your needs, you will need a custom script, what will handle carry-over-day your way, for example:

$start = new DateTime('31 January 2011');

$new   = clone $start;
$new->modify('first day of next month'); 
$newDay = ($start->format('j') > $new->format('t') ? $new->format('t') : $start->format('j')) - 1;
$new->modify("+{$newDay} days");

echo $start->format('Y-m-d'), " > ", $new->format('Y-m-d');

demo

Community
  • 1
  • 1
Glavić
  • 42,781
  • 13
  • 77
  • 107