Laravel created_at return object in place of date format in database?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel created_at Return Object: Fixing Date Formatting in Your API Responses

As developers building APIs with Laravel, one of the most common little frustrations involves handling Eloquent timestamps. You expect a simple date string when you request data, but sometimes, the underlying structure of Carbon objects leaks into your JSON response, resulting in verbose and confusing output instead of clean dates.

This post dives deep into why this happens and provides robust solutions to ensure your API responses are clean, predictable, and exactly what your frontend expects.

The Mystery Behind the Complex Object

You are attempting to retrieve created_at from your database and return it in a JSON response. When working with Laravel and Eloquent, the timestamps stored in the database (usually as UTC timestamps) are mapped to Carbon objects within your Eloquent model.

The issue you are observing—receiving an object like { date: "2016-07-18 00:00:00.000000", timezone_type: 3, timezone: "UTC" } instead of a simple date string—happens because when Laravel serializes the model attributes (often via toArray() or an API resource), it includes the full metadata associated with the underlying Carbon instance to preserve time zone and precision information.

This is not an error in your database; it’s a feature of how PHP/Carbon objects are serialized, which we need to control when building APIs.

Solution 1: Simple Formatting on Retrieval (The Quick Fix)

For simple cases where you only need the date string immediately upon retrieval, you can format the attribute directly in your controller or service layer before returning the response. This is effective for one-off requests but less maintainable for complex models.

If you are fetching a single record:

php
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function show(User $user)
    {
        // Format the created_at attribute directly to a standard ISO format string
        $formattedCreatedAt = $user->created_at->toDateTimeString();

        return response()->json([
            'id' => $user->id,
            'name' => $user->name,
            'created_at' => $formattedCreatedAt, // Clean output
        ]);
    }
}

While this solves the immediate display problem, relying on manual formatting scattered across controllers is not scalable.

Solution 2: Implementing Eloquent Accessors (The Best Practice)

The most professional and Laravel-idiomatic way to handle attribute presentation is by using Accessors within your Eloquent Model. This keeps the presentation logic encapsulated within the model itself, making your code cleaner and ensuring consistency wherever that model is used.

We can define an accessor on the User model to ensure that whenever we access created_at, it returns a nicely formatted string, regardless of how the underlying Carbon object is structured internally.

Step 1: Update the Model

In your app/Models/User.php file, add an accessor:

php
<?php

namespace App\Models;

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

class User extends Model
{
    /**
     * Get the created at as a nicely formatted string.
     */
    protected function createdAt(): Attribute
    {
        return new Attribute(
            get: fn ($value, $attributes) => $value ? $value->toIso8601String() : null
        );
    }
}

Note: Newer Laravel versions (9+) prefer using the Attribute class for casting and accessing attributes.

Step 2: Use the Accessor in Your Controller

Now, when you retrieve the model and return it, Eloquent automatically handles the formatting defined in the model. You can often skip manual formatting entirely:

php
use App\Models\User;

class UserController extends Controller
{
    public function getFormattedData(User $user)
    {
        // Eloquent handles the formatting automatically via the accessor
        return response()->json([
            'id' => $user->id,
            'name' => $user->name,
            'created_at' => $user->created_at, // Returns the clean string defined in the model
        ]);
    }
}

By implementing this pattern, you ensure that your data layer adheres to the principle of separation of concerns. This approach aligns perfectly with Laravel’s philosophy of building robust, elegant applications, much like the frameworks provided by the Laravel Company team aims to achieve.

Conclusion

Dealing with date and time formatting in API responses is a common hurdle. While simple manual formatting works for quick fixes, leveraging Eloquent Accessors (or Mutators) is the superior, scalable solution. It centralizes your data presentation logic within the model, making your application easier to maintain, debug, and understand. Always strive for clean data contracts when building APIs!