I have an issue with the time returned from my database, everything is 2 hours in the past.
I’ve been troubleshooting this issue for a bit, and checked the following:
/etc/php.ini is only ini in use and has date.timezone = Europe/Amsterdam
.(also restarted apache)
Laravel’s app.php config has 'timezone' => 'Europe/Amsterdam'
.
I ran config:clear
and config:cache
.
I was able to boil the issue down to Carbon.
I have a route which simply returns Carbon::now()
and it shows 2021-07-09 10:58:31.874837Z
(2 hours early)
If I modify the code to Carbon::now()->format("Y-m-d H:i:s")
it returns 2021-07-09 12:58:31
which is the correct time.
If I run tinker, and then run Carbon/Carbon::now()
it directly shows the correct time(locally on Win 10 AND on the centos server)
I’m not sure why carbon shows a different time when formatted, did I miss a config somewhere?
Thank you in advance.
NOTE:
If I use tinker, I’m getting the correct time from both my DB(which’s timezone is CEST) and Carbon::now()
2
Answers
You open with
Your database might be the key here: Does the data stored there come with a timezone? Is it expected in a specific timezone? The database probably returns UTC, which is exactly 2h off of CET (Amsterdam time) during summer. And your application interprets this time as CET. Thus, the time is 2h behind
My recommendation is to not bother with timezones anywhere in the technical layer and only format to the user’s timezone in the UI. E.g. have all your servers run on UTC only. Store time in UTC. Calculate whatever you need in UTC. And for display, convert to the current user’s preferred timezone.
And that recommendation might be precisely what you’re running into: Your database just stores UTC times, which you interpret as CET. Don’t do that. It’ll result in a mess with the next change to daylight saving time in autumn of this year.
Add on:
Even (or especially) after your note, I stand by what I wrote above: Have all your technical infrastructure purely work on UTC, always. This means there will never ever be any conversion until the very last moment, when the time is converted to the user’s preferred timezone. Or if there is, it’s trivial to find the culprit. All hell breaks lose when you routinely involve timezone math in all operations (other than to/from UTC conversions). Especially around the time of daylight saving time changes (which happen at different dates in different regions, and in different directions on both hemispheres)
What is "show" in the first sentence, because, this is not possible that the object would have a different timezone or value that what you see when you format it using
format("Y-m-d H:i:s")
2021-07-09 10:58:31
here is the result of the datetime converted into UTC.So my guess is that you’re talking about a JSON output, and what you see is actually
2021-07-09T10:58:31Z
and not2021-07-09 10:58:31
, in this case it’s correct, theZ
here is very important to be kept as it means "Zulu = GMT" and will allow the JSON reader (such as a web browser) to construct the correct date anywhere on earth while if2021-07-09 12:58:31
would be returned, the reader would have no clue what timezone it is.