クマの手も借りたい
馬とテニスとリラックマが好きな IT 系のエンジニアです。
PHP

PHPのCarbonで月末から正しく翌月末の日付を求める

PHP に限ったことではないですが、日付関数の 1 ヶ月後や 1 ヶ月前にはいろいろと苦労してきました。

これには 2038 年問題とはまた違った、今すぐにでも起こりえる問題だからです。

今回は Carbon の便利な機能について紹介します。

日付で苦労するパターン

例えば、PHP の date 関数や strtotime 関数で 1 ヶ月後の結果を求める際、以下のようなロジックを書くことが多いと思います。

$ php -r "date('Y-m-d', strtotime('+1 month'));"

2018-01-16

これが、今日みたいに 2017-12-16 であれば、2018-01-16 が返ってきます。

1 ヶ月後は年が変わっているのかと思うとなんだか切ないですね。

しかし、今日が 2018-01-31 だったらどうでしょうか。

$ php -r "date('Y-m-d', strtotime('20180131 +1 month'));"

2018-03-03

まあ、よくある話ですよね。MySQL の日付関数でも同様の問題は発生するので、この手のパターンはいつも調整していました。

CarbonのaddMonthsNoOverflowで柔軟に対応

最近は composer を利用することが多いので、日付操作にも Carbon を使っています。

strtotime の 2038 年問題が気になっているわけではないですが、PHP としても日付は DateTime を使うことを推奨していることですし。

ちなみに、2038 年に 32bit のサーバを動かしているシステムがあるとも思えないので、シビアに考えることはないですけどね。

さて、話が少し脱線しましたが、Carbon には addMonthsNoOverflow() というメソッドが用意されていて、ここに 1 を渡した場合は、2018-02-28 が返ってくるのです。

$inudoshi = new Carbon('2018-01-31');
$inudoshi->addMonthsNoOverflow(1);

date や strtotime を使っていた頃みたいに、変にラッパー関数を書かなくても、Carbon なら問題なく翌月や先月の操作ができます。

ちなみに、addYearsNoOverflow() はないですが、addMonthsNoOverflow を応用して、引数を 1 * Carbon::MONTHS_PER_YEAR にしても良さそうです。

// うるう日の1年後
$inudoshi = new Carbon('2016-02-29');
$inudoshi->addMonthsNoOverflow(1 * Carbon::MONTHS_PER_YEAR);
Web API The Good Parts

オライリーの「Web API」に特化した本です。最近の多くの Web サービスは API が活用されていますが、その技術はこれまでの Web サイトとそれほど大きく変わりません。

今後、マイクロサービス化が進む中で知っておいて損はない内容が詰め込まれており、現場のエンジニアやこれから Web 系のエンジニアを目指す人にもオススメの一冊です。

created by Rinker
¥2,376
(2018/09/21 11:58:20時点 Amazon調べ-詳細)

あなたにオススメ