Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

thomas_inckx's avatar

Date accessor vs. protected $dates (L5.2)

Hi all,

I'm trying to figure out the best way to manage (get & set) dates in my app. The protected $dates array is a great tool. It automatically converts a date string to a Carbon object, and it makes storing the dates easy and uniform (I use mutators).

protected $dates = ['birth_date'];

I can now echo a date in my view like this:

{{ $user->birth_date->format(config('view.date_format')) }}

That's ok, but kinda redundant. It means I have to do this in every view, for every date attribute (I have a lot of 'em). So I was checking out the accessors. I assumed I could simply create an accessor:

public function getBirthDateAttribute($date) {
    return $date->format(config('view.date_format'));
}

and then in my view:

{{ $user->birth_date }}

and get a nicely formatted date. But this isn't working. The $date is still a simple string at this moment. It seems that it's only converted to a Carbon object after the accessor is called. My conclusion is that the accessors don't make sense in combination with the $dates array and I'll have to format each Carbon object manually in my views.

Am I right?

EDIT: as it turns out, in my case, I don't need the $dates array. I seems that I just need to define an accessor and a mutator:

public function getBirthDateAttribute( $date )
{
    $date = Carbon::createFromFormat(config('view.def_date_format'), $date);

    return $date->format(config('view.date_format'));
}


public function setBirthDateAttribute( $date )
{
    $this->attributes['birth_date'] = Carbon::createFromFormat( config( 'view.date_format' ),       
    $date );
}

, and everything works as it should. Don't hesitate to share your view though, if you see it differently.

0 likes
6 replies
Paschal's avatar

I believe when you use the protected $dates array, Laravel automatically has and calls an accessor to convert the date string to a Carbon object so the mutator in your view won't get called.

I'm not too sure but I believe so.

thomas_inckx's avatar

Laravel indeed converts the date to a Carbon object in case of the $dates array, but it isn't formatted like I want, and that's my point. But if you define an accessor, it gets called before the conversion.

Paschal's avatar

@thomas_inckx Well, by normal OOP convention, your method should be called first and not just called first but the only method called so it shouldn't call the default accessor. (Method Overriding)

I just overrid the created_at on my User model and my own function was called: getCreatedAttribute() and it wasn't converted to a Carbon instance.

I wonder why yours is behaving strangely. Try and override the created_at attribute and see what is returned.

thomas_inckx's avatar

Thanks for your reply, Paschal. I do think however that you might misunderstand me. What your describing, is the same in my case, obviously.

getCreatedAtAttribute() is overriding the conversion to a Carbon object. While I assumed that it would get called after the conversion.

Anyway, like I said, I managed to make things work without the $dates array.

Cronix's avatar

I just made a generic helper function which can be used on any model/view. It checks to see if the passed in date is a carbon instance, if not it makes it one. It converts the date to the users local timezone and returns a formatted date (format is optionally passed to function, else uses a default one).

So I just {{ dateFormat($user->birth_date, 'n/j/Y') }} and skip the $dates array and accessors/mutators.

I have a counterpart, setDateFormat(), which converts to UTC and also an optional format (so you can use it for time/date/datetime types) for storing in the db.

I deal with a ton of dates, times, etc, across many timezones, and this helped to keep things dry quite a bit.

1 like

Please or to participate in this conversation.