Mutable Carbon Dates Errors: Use copy() or CarbonImmutable

This is a typical error I see developers making: using $date->addDays(1) and then another $date->addYears(1) in the same request and getting wrong results. Let me explain.

If you perform multiple modification operations with a typical Carbon object, it will change the original object.

1$now = now();
2// Result: 2023-01-17 09:08:49
3 
4$tomorrow = $now->addDays(1);
5// Result: 2023-01-18 09:08:49
6 
7$twoDaysOrThreeDays = $now->addDays(2);
8// Result: 2023-01-20 09:08:49

As you can see, the initial variable is January 17, and the $now->addDays(2) adds those two days not to the initial variable, but to the $tomorrow variable.

In other words, this is what happens under the hood:

1$now = $tomorrow = $now->addDays(1);

So, if you want to perform a few operations with the same Carbon object in the same request, be aware of this behavior and potential errors.

What are your options to override it?


Option 1. Use copy()

You can create a "temporary" object of $now, specifically for that one operation, by using the copy() method.

1$tomorrow = $now->copy()->addDays(1);
2$twoDaysOrThreeDays = $now->copy()->addDays(2);
3 
4// The $now value will stay the same

Option 2. Use CarbonImmutable

The default now() Laravel helper, or Carbon::now() creates the mutable objects by default. But you can specifically create the objects that would not carry this behavior:

1$now = Carbon\CarbonImmutable::now();
2 
3$tomorrow = $now->addDays(1);
4$twoDaysOrThreeDays = $now->addDays(2);

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month

Recent Premium Tutorials