web-dev-qa-db-ja.com

Carbon-なぜaddMonths()は月の日を変更するのですか?

簡単な例を次に示します(今日は2016-08-29):

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

出力:

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

Carbon::now()->addMonths(6)の場合、_2017-02-29_ではなく_2017-03-01_が必要です。

日付の変更について何か不足していますか?

11
Limon Monte

2017年2月29日はありません。うるう年は2016年に起こりました。

次のリンク:

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

は、2012年1月31日に1か月を加算し、2012年3月3日に到着する例を示しています。これは意図されていますが、私には混乱しているようです。


SQLで異なる動作を示す反例として:

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

結果は2012年2月29日になるため、使用する予定のaddmonth()関数の仕様を確認することをお勧めします。

12
RIanGillis

それはそれよりさらに不自由です-減算には同じ問題があります。ただし、オーバーフローを回避するための特別な方法があります。

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

出力:

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