logo

Making Eloquent's date cast strip time on write

For when you can't change the column to DATE

Joel Clermont
Joel Clermont
2026-10-20

In an earlier tip, I showed that Eloquent's date cast only strips the time when you read a value. On write, the full time still goes to the database, and a DATETIME column keeps it.

The best fix is a DATE column. But sometimes you can't change the schema, like with a legacy database or a table another system owns.

In that case, a small custom cast can fix the asymmetry.

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

class DateOnly implements CastsAttributes
{
    public function get(Model $model, string $key, mixed $value, array $attributes): ?Carbon
    {
        return $value === null ? null : Carbon::parse($value)->startOfDay();
    }

    public function set(Model $model, string $key, mixed $value, array $attributes): ?string
    {
        return $value === null ? null : Carbon::parse($value)->toDateString();
    }
}

The get method behaves like the built-in cast and hands you a Carbon instance at midnight. The set method is the key part that Laravel's cast skips. It drops the time before the value reaches the database.

protected function casts(): array
{
    return [
        'start_date' => DateOnly::class,
    ];
}
$record->start_date = '2023-05-15 14:30:45';
$record->save();

DB::table('events')->where('id', $record->id)->value('start_date');
// 2023-05-15 00:00:00

Now, what Eloquent shows you actually matches what the database holds.

It's also key to not skip the null checks. Carbon::parse(null) returns the current time, so without them a nullable column would quietly fill up with today's date.

Here to help,

Joel

P.S. A test that reads the raw column through the DB facade catches this kind of mismatch right away. Our testing workshop shows you how to write tests that check what actually gets stored.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.