Mastering Date Serialization in Laravel: Customizing Your Model's Date Formats

Mastering Date Serialization in Laravel: Customizing Your Model's Date Formats

When working with dates in Laravel, you often need to control how they're formatted when your models are converted to arrays or JSON. Laravel provides powerful tools to customize date serialization, allowing you to maintain consistent date formats across your application. Let's dive into how you can leverage these features.

Global Date Serialization

Laravel allows you to customize the default serialization format for all date attributes in your models. You can do this by overriding the serializeDate method in your model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DateTimeInterface;

class YourModel extends Model
{
    /**
     * Prepare a date for array / JSON serialization.
     *
     * @param  \DateTimeInterface  $date
     * @return string
     */
    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d');
    }
}

This method will be used for all date attributes in the model, including created_at and updated_at.

Per-Attribute Date Formatting

If you need different formats for different date attributes, you can specify them in the model's $casts property:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Event extends Model
{
    protected $casts = [
        'start_date' => 'date:Y-m-d',
        'end_date' => 'date:Y-m-d',
        'created_at' => 'datetime:Y-m-d H:i:s',
        'updated_at' => 'datetime:Y-m-d H:i:s',
    ];
}

This approach allows you to have fine-grained control over each date attribute's format.

Dynamic Date Formatting

Sometimes, you might need to change the date format dynamically. You can achieve this by using accessors:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;

class Event extends Model
{
    protected function startDate(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value->format('Y-m-d'),
        );
    }
}

This allows you to apply custom formatting logic that can change based on certain conditions.

Practical Example

Let's consider a more comprehensive example where we have an Appointment model that needs different date formats for different scenarios:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use DateTimeInterface;

class Appointment extends Model
{
    protected $casts = [
        'start_time' => 'datetime',
        'end_time' => 'datetime',
    ];

    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format('Y-m-d H:i:s');
    }

    protected function startTime(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value->format('g:i A'),
        );
    }

    protected function endTime(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value->format('g:i A'),
        );
    }

    protected function dateForHumans(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->start_time->format('F j, Y'),
        );
    }

    public function toArray()
    {
        $array = parent::toArray();
        $array['date_for_humans'] = $this->date_for_humans;
        return $array;
    }
}

By leveraging Laravel's date serialization features, you can ensure that your API responses and array representations of models always include dates in the format that best suits your application's needs. This level of control allows you to create more user-friendly and consistent data presentations across your entire Laravel application.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe