Laravel Immutable Carbon Dates
Tags: laravel, php, webdev, beginners
Published: 2024-05-29 09:35:24

In this article we're going to look at the Carbon data class in laravel and how we can change the settings of how laravel uses the class to make it immutable.

## What's the problem we're trying to solve?
When you're working with dates in Laravel you will most likely be using the Carbon class. This class is a wrapper around the PHP DateTime class and provides a lot of useful methods for working with dates.

When you output the value of a carbon object you get this value.

```php
$now = now()
= Illuminate\Support\Carbon @1716793925 {#5324
    date: 2024-05-27 08:13:50.554997 Europe/London (+01:00),
  }
```

You can change this object by adding or subtracting time from the object with helper helpers like `->addHour()`.

```php
$now = $now->addHour()
= Illuminate\Support\Carbon @1716797621 {#5329
    date: 2024-05-27 09:13:50.554997 Europe/London (+01:00),
  }
```

You can add multiple hours by using the method `->addHours(4)`.

```php
$now = $now->addHours(4)
= Illuminate\Support\Carbon @1716812090 {#5318
    date: 2024-05-27 13:13:50.554997 Europe/London (+01:00),
  }
```

But we have a problem, adding 4 hours to 8:12 should be 12:12 not 13:13. This is because the Carbon class is mutable and when you call the addHours method it changes the original object.

This can have it's advantages when you have a large process of changing the date multiple times but it can also have it' s disadvantages when you want to keep the original date.

Carbon has a method called copy that will create a new instance of the Carbon object and then you can change the new object.

```php
$now = now()
= Illuminate\Support\Carbon @1716793925 {#5324
    date: 2024-05-27 08:13:50.554997 Europe/London (+01:00),
  }

$nowCopy = $now->copy()->addHours(4)
= Illuminate\Support\Carbon @1716812090 {#5318
    date: 2024-05-27 12:13:50.554997 Europe/London (+01:00),
  }
```

The other approach is to use the `CarbonImmutable` class which is a subclass of the Carbon class but it's immutable.

```php
$now = Carbon\CarbonImmutable::now();
= Carbon\CarbonImmutable @1716794377 {#5341
    date: 2024-05-27 08:19:37.149971 Europe/London (+01:00),
  }

$now->addHour()
= Carbon\CarbonImmutable @1716797977 {#5394
    date: 2024-05-27 09:19:37.149971 Europe/London (+01:00),
  }

$now->addHours(4)
= Carbon\CarbonImmutable @1716808777 {#5335
    date: 2024-05-27 12:19:37.149971 Europe/London (+01:00),
  }
```

As you can see when we add 1 hour and then 4 hours we get the result of 4 hours not 5 hours. Now we get the expected results when working with dates.

This is a simple change to make in your application but it can have a big impact on how you work with dates in your application.

## Changing the default Carbon class
If you want to change the default Carbon class to be immutable you can do this by adding the following code to your `AppServiceProvider` class.

```php
use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Date;

public function boot()
{
    Date::use(CarbonImmutable::class);
}
```

This will change the default Carbon class to be CarbonImmutable and now all dates in your application will be immutable.

This is a simple change to make in your application but it can have a big impact on how you work with dates in your application.

## Performance Implications
There are some performance implications when using the `CarbonImmutable` class. The `CarbonImmutable` class is slower than the Carbon class because it creates a new instance of the object every time you call a method that changes the date.

This is because the CarbonImmutable class is immutable and it doesn't change the original object. This can have a big impact on the performance of your application if you're working with a lot of dates.

You should consider the performance implications when deciding whether to use the CarbonImmutable class or the Carbon class in your application.