Laravel Refactoring to Carbon Macros

June 10, 2024 · 3 min read

When working with dates in Laravel, Carbon is a very helpful library that provides many functionalities to easily handle date and time operations. However, there might be cases where you require specific functionality that isn’t provided out of the box. That’s where macros come into play. In this blog post, we will only focus on Carbon Macros, however, a lot of Laravel Facades support Macros such as Blade, Collection, etc.
Understanding Carbon Macros
Carbon macros allow developers to extend the capabilities of Carbon by defining custom methods. Think of it as adding your own toolkit to an already robust set of tools. This feature is particularly useful when you have complex date calculations or formatting that you find yourself repeatedly using across different parts of your Laravel application.
Let’s dive into how you can refactor your code to make use of Carbon macros, improving maintainability and readability along the way.
Using Carbon Macros
Identify repeated date operations
Before diving into writing macros, look through your codebase for date operations you’re using frequently. If you see a pattern or a specific operation you keep repeating, that’s a good thing to turn into a Carbon macro.
Define the macro
Carbon macros are defined using the macro method. This is typically done within a service provider, such as AppServiceProvider. Here’s an example:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Carbon::macro('toUserTimezone', fn (): Carbon => $this->tz(auth()->user()?->timezone ?? config('app.default_timezone')));
}
}In this snippet, we’ve created a macro called toUserTimezone, which formats a Carbon instance to the user’s timezone or defaults to our Default Timezone. The $this keyword refers to the Carbon instance on which the macro is called.
Use the macro throughout your application
Once you’ve made the macro, you can use it anywhere in your Laravel app just like any other Carbon method:
$date = Carbon::now()->toUserTimezone();This code gives you a Carbon date in the user’s timezone. It’s simpler and clearer than writing the same timezone code over and over.
Testing your Carbon macro
Always write tests to ensure your macro works as expected. Testing is a crucial part of maintaining the reliability of your application. Create a unit test that checks if the macro returns the specified format.
Here is a sample Pest test that we wrote for this Macro:
it('converts carbon date to user timezone', function () {
// Create user and login
$user = User::factory()->make();
Auth::login($user);
// Set default timezone in config
config()->set('app.default_timezone', 'UTC');
// Create a Carbon instance
$date = Carbon::now('UTC');
// Apply macro
$userDate = $date->toUserTimezone();
// Check if timezone is converted correctly
expect($userDate->timezoneName)
->toBe($user->timezone);
});Document your Carbon macros
Like any other part of your code, documentation is important for macros. Make sure you write down what each macro does, the return type, and any parameters it takes. This will help other programmers (or even your future self) understand what the macro is for.
Conclusion
Carbon macros are a great way to extend the Carbon library and make it fit what your project needs. By following the steps above, you can refactor your Laravel application to use Carbon macros, resulting in cleaner, more maintainable code. Remember to always keep an eye out for repetitive code patterns that could be simplified with a custom macro. Your future self will thank you.
Bring Your Ideas to Life 🚀
If you need help with a Laravel project let’s get in touch.
Lucky Media is proud to be recognized as a leading Laravel Development Agency
Technologies

Stay up-to-date
Be updated with all news, products and tips we share!

