Carbon - why addMonths() change the day of month?
Asked Answered
L

2

16

Here's the simple example (today is 2016-08-29):

var_dump(Carbon::now());
var_dump(Carbon::now()->addMonths(6));

Output:

object(Carbon\Carbon)#303 (3) {
  ["date"] => string(26) "2016-08-29 15:37:11.000000"
}
object(Carbon\Carbon)#303 (3) {
  ["date"] => string(26) "2017-03-01 15:37:11.000000"
}

For Carbon::now()->addMonths(6) I'm expecting 2017-02-29, not 2017-03-01.

Am I missing something about date modifications?

Louisalouisburg answered 29/8, 2016 at 13:42 Comment(1)
2017-02-29 doesn't exist :-).Silvan
C
16

There is no 2/29/2017. Leap-year happened in 2016.

The following link:

http://carbon.nesbot.com/docs/#api-addsub

provides an example of adding 1 month to 1/31/2012 and arriving on 3/3/2012. Which is intended, though seems confusing to me.


As a counter-example exhibiting different behavior, in SQL:

SELECT dateadd(m,1,'2012-01-31') 

results in 2/29/2012, so it would be a good idea to check the specifications of whatever addmonth() function you plan on using.

Cyclone answered 29/8, 2016 at 13:46 Comment(0)
R
23

It's even more crippled than that - subtraction has same issues. There are special methods to avoid overflows, though:

function original(){ 
    return new Carbon('2016-08-31'); 
};
function print_dt($name, $date){ 
    echo $name . $date->toAtomString() . PHP_EOL; 
};

print_dt('original:            ', original());
echo '-----' . PHP_EOL;
print_dt('addMonths:           ', original()->addMonths(6));
print_dt('addMonthsNoOverflow: ', original()->addMonthsNoOverflow(6));
echo '-----' . PHP_EOL;
print_dt('subMonths:           ', original()->subMonths(2));
print_dt('subMonthsNoOverflow: ', original()->subMonthsNoOverflow(2));

output:

original:            2016-08-31T00:00:00+00:00
----- 
addMonths:           2017-03-03T00:00:00+00:00
addMonthsNoOverflow: 2017-02-28T00:00:00+00:00
----- 
subMonths:           2016-07-01T00:00:00+00:00
subMonthsNoOverflow: 2016-06-30T00:00:00+00:00
Rudman answered 28/3, 2017 at 11:17 Comment(0)
C
16

There is no 2/29/2017. Leap-year happened in 2016.

The following link:

http://carbon.nesbot.com/docs/#api-addsub

provides an example of adding 1 month to 1/31/2012 and arriving on 3/3/2012. Which is intended, though seems confusing to me.


As a counter-example exhibiting different behavior, in SQL:

SELECT dateadd(m,1,'2012-01-31') 

results in 2/29/2012, so it would be a good idea to check the specifications of whatever addmonth() function you plan on using.

Cyclone answered 29/8, 2016 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.