AceVez
AceVez

Reputation: 301

Carbon doesn't automatically convert timezone when using `diffForHumans()` on Laravel

I'm new to Laravel and was messing around with Carbon (this is the first time I use it or even heard about it).

I made a simple blog where it displays comment's created_at (a timestamp column) with Carbon's diffForHuman(). I managed to show it but instead of "x minutes ago" it shows "z hours from now" (exactly the difference between my timezone and UTC which is UTC+z) as if the comments come from the future.

Here is my code:

{{ $comment->created_at->diffForHumans() }}

Since I never change the timezone in my config/app.php, I assume that Carbon doesn't automatically convert timestamp into current timezone on diffForHumans().

Do I have to explicitly set the timezone to make Carbon shows the right diff? Or is there something I did wrong?

EDIT: I'm fully aware of what apokryfos said about time conversion (save it in UTC and convert it to client's timezone for display).

I noticed a few things. First of all, I run my app with php artisan serve and my DB (10.1.33-MariaDB) with XAMPP. Therefore my app's timezone is UTC (the default config) and my DB is the same as my machine (UTC+z). So I'm thinking that maybe when my app retrieved the created_at``timestamp, my DB returned created_at in my machine's timezone (UTC+z) which is weird. Why doesn't Laravel automatically convert timestamp into the app's timezone on retrieval if this is the case? Is it possible that the returned timestamp's timezone is treated as if it has the same timezone as the app?

Upvotes: 1

Views: 3020

Answers (2)

AceVez
AceVez

Reputation: 301

This happened because my app and my DB have a different timezone. My DB run with XAMPP and has the same timezone as my machine (UTC+z) and my app run with php artisan serve so and has the timezone of the default configuration (UTC).

After configuring my app into the same timezone as my machine, Carbon's diffForHumans() shows the correct diff.

Upvotes: 1

ali
ali

Reputation: 862

you can apply the time zone on the date before return in the model using accessor as the following:

    public function getCreatedAtAttribute($date)
{
    return Carbon::parse($date)->timezone('your time zone goes here'); //example  Europe/Amsterdam
}

Upvotes: 2

Related Questions