5
5

Carbon使用時に注意すること【Laravel】

Last updated at Posted at 2023-04-03

CarbonオブジェクトはMutable(変更可能)という特性を持っています。
Mutableは便利である反面、注意しなければならない点もあるため、自分用のメモも兼ねて記事を書かせて頂きます。

Carbonとは?

日付と時刻を簡単に操作できるライブラリです。DateTimeクラスを拡張しており色々と便利なメソッドが利用できます。

Mutableとは?

Mutableとは、オブジェクトの状態が変更可能であるということです。
例えば以下コードのように$date1に対して2023年4月1日という日付のcarbonインスタンスを代入し、
addDaysメソッドを使って、そこから7日後の日付(4月8日)を$date2に代入したとします。

$date1 = Carbon::createFromDate(2023, 4, 1); 
$date2 = $date1->addDays(7); 

この状態で、diffInDaysメソッドを使って$date1$date2の差が何日なのかを確認してみます。
当然7日になるだろうと思いますが、、

dd($date1->diffInDays($date2));

// 出力結果「0」

なんと「0」日になってしまいました。

なぜこんなことが起きるのでしょうか?
それは、以下の行で$date1自体も4月1日から4月8日に変更になっているからです。

$date2 = $date1->addDays(7); 

つまり、$data1 = ~~ といった形で代入をしなくても
$date1->addDays(7); とするだけで状態を変更できるということです。

$date1 = Carbon::createFromDate(2023, 4, 1); 
$date1->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-8」

これがMutable(変更可能)なオブジェクトの特性です。
便利な側面もありますが、気付かずに意図しない変更が行われてしまう可能性もあります。

意図しない変更を避ける方法

方法①:copy()を使う

以下のように、$date1に対してcopyメソッドを使って複製を作ったあとにaddDaysメソッドを使用すれば$date1は4月1日のままです。

$date1 = Carbon::createFromDate(2023, 4, 1); 
$date2 = $date1->copy()->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-1」
方法②:CarbonImmutableを使う

以下のように、CarbonクラスではなくCarbonImmutableクラスを使用するとMutable(変更可能)ではないインスタンスが作成されるので、意図しない変更を避けることができます。

$date1 = CarbonImmutable::createFromDate(2023, 4, 1); 
$date2 = $date1->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-1」

なお、MutableとImmutableは、以下のようにtoImmutableメソッドやtoMutableメソッドを使用して相互変換が可能です。

$date1 = Carbon::now(); 
$date1->toImmutable();
// Immutableに変換

$date2 = CarbonImmutable::now(); 
$date2->toMutable();
// Mutableに変換
5
5
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5