web-dev-qa-db-fra.com

Carbon - pourquoi addMonths () change le jour du mois?

Voici l'exemple simple (aujourd'hui est le 29/08/2016):

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

Production:

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"
}

Pour Carbon::now()->addMonths(6) j'attends 2017-02-29, Pas 2017-03-01.

Suis-je en train de manquer quelque chose au sujet des modifications de date?

11
Limon Monte

Il n'y a pas de 29/02/2017. L'année bissextile s'est produite en 2016.

Le lien suivant:

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

fournit un exemple d'ajout de 1 mois au 31/01/2012 et d'arrivée le 03/03/2012. Ce qui est destiné, mais me semble confus.


Comme contre-exemple présentant un comportement différent, en SQL:

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

résultats au 29/02/2012, il serait donc judicieux de vérifier les spécifications de la fonction addmonth () que vous prévoyez d'utiliser.

12
RIanGillis

C'est encore plus paralysé que cela - la soustraction a les mêmes problèmes. Il existe cependant des méthodes spéciales pour éviter les débordements:

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));

production:

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
12
Alexander Malakhov