m4rinos's avatar

created_at hours displaying wrong

I have a model with sessions belonging to a user. In the Session model i've added:

	protected $casts = [
		'items' => 'array',
		'created_at' => 'datetime:Y-m-d H:i:s',
	];

when I print out the session.created_at it returns the wrong hour. My initial idea was that this must be a timezone issue, so I set 'timezone' => 'Asia/Singapore', in app.php and cleared the caches. But still I get a wrong hour. When I dump out the carbon date (dd(Carbon::now())) it show the right time, when I look at the database field, its also correct (sqlite).

it shows 2021-01-06 11:20:52, without the cast it shows 2021-01-06T11:20:52.000000Z, by database field shows 2021-01-06 19:20:52 (correct) and the Carbon dump shows date: 2021-01-06 19:51:11.161307 Asia/Singapore (+08:00) (which is the correct time now)

I have the feeling I am overlooking something very obvious, but I just can't figure it out.

Anybody see whats wrong here?

0 likes
15 replies
newbie360's avatar

what if remove

// 'created_at' => 'datetime:Y-m-d H:i:s',
m4rinos's avatar

then it just shows as the raw date 2021-01-06T11:20:52.000000Z again :D The whole point of this was to have the created_at date formatted so I don't have to do that in my views, that will remove that format.

newbie360's avatar

set 'timezone' => 'Asia/Singapore' in config/app.php

and delete this line

// 'created_at' => 'datetime:Y-m-d H:i:s',
1 like
m4rinos's avatar

as you can read in my post, I have set the timezone exactly like that. Why I don't delete that line I've just explained right?

newbie360's avatar

well i'dont know what happen, but what i did is just change 'timezone' in config/app.php and all running fine

default Laravel will auto handle the created_at, updated_at, deleted_at

but if change the db record outside Laravel, the time is depends on the server setting

for example if insert a record in phpMyAdmin and use now(), the time is base on the server not the Laravel timezone setting

and the info of dd(now()) for me is useless, $user->created_at thats all

and about you session.created_at, did you try delete all files in storage/framework/sessions and check again

otherwise, no idea whats wrong..

munazzil's avatar

You have to declare as like below in your model otherwise project takes automatic datetime with timestamps,

          public $timestamps = false;
1 like
m4rinos's avatar

isn't that to disable using timestamps all together? Anyway I tried it and it did not work.

The ultimate goal of this was to set my model in a way that I do not have to format my date in my views, not remove the timestamps...

m4rinos's avatar
m4rinos
OP
Best Answer
Level 7

In the end I was not able to figure out where the problem was, so I ended up using the MomentJs library and formatted the date in the frontend after all.

I would be happy to hear any solution, but for now I guess I'll stick to this.

chiefguru's avatar

@m4rinos you could have simply created your own attribute on the model and returned the formatted date time.

public function getFullNameAttribute()
{
    return $this->firstname . ' ' . $this->lastname;
}
m4rinos's avatar

You mean I could have used Carbon to format it as function in the Model instead of MomentJs? Yes, I guess I could have done that. I'm using it in a vue template so I guess momentjs makes more sense in the end for me but thanks for your feedback.

For this question I was hoping to understand why the cast displayed such strange behaviour, I would have like to use that option. I used it in the same way as the doc: https://laravel.com/docs/8.x/eloquent-mutators#date-casting

spyworld's avatar

You can try to create a new provider and factory carbon again. You can customize it.

thamibn's avatar

Hi Go to the model and add the below code it seems its a intentionally change by laravel you can read about it on this link https://laravel.com/docs/7.x/upgrade#date-serialization

use DateTimeInterface;

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

the above code will use your timezone on config/app

the issue was reported and closed find below link https://github.com/laravel/framework/issues/31722

2 likes
muhammadrahban4's avatar
public function getCreatedAtAttribute($date)
{
	 return Carbon::parse($date)->setTimezone('Asia/Karachi')->format('Y-m-d g:i A');
}

use this code I have the same issue in my case I can't use momentjs that's why I used this method "get[column name (CamelCase)]Attribute" and setTimezone([your time zome])

1 like
Rida Makhchan's avatar

Facing the same issue, tried to understand the logic although timezone on DB is correct (same on PHP.ini, Same on app/config.php), the final users see different timzeone. As a Workarround I used timezone with Carbon on Model :

 use Carbon\Carbon;

     public function getCreatedAtAttribute($date)
    {
        return Carbon::parse($date)->setTimezone('Asia/Riyadh');
    } 
1 like

Please or to participate in this conversation.