framework: toArray uses incorrect timezone.
- Laravel Version: 7.0
- PHP Version: 7.3
- Database Driver & Version: Mysql 5.6
Description:
When using the toArray() method on a modal, it does not show the timestamps in the correct timezone.
Steps To Reproduce:
-
Set the
app.phptimezone toAmerica/Toronto -
Insert some rows for any model you want
-
Create a blade file with this code for the model:
created_at: {{ $model->created_at }} <br><br> via array: {{ print_r($model->toArray(), true) }}
You can clearly see that $model->created_at is showing the correct date via the exact database value, and for whatever reason toArray is deciding to change it to UTC.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 19 (10 by maintainers)
@viirre @taylorotwell I really think it is wrong.
Carbon::toJSON()method will create a copy of current$dateand set it toutc(), ignoring theapp.timezone. So non-UTC dates will have a wrong output whentoArray()or similar is called. It is really intentional?A simple solution is modify how
serializeDate()works by callingtoISOString(true)instead oftoJSON(). ThetrueontoISOString(true)means “do not set timezone to UTF, keep as is”.That’s intentional: https://laravel.com/docs/7.x/upgrade#date-serialization
I know this issue is closed but I’m trying anyway with a similar problem caused by this change.
There are some cases where this change might cause issues for a lot of apps, ours included. Consider:
If the
Invoicemodel has adatecast for the thedateattribute, the date will be saved as2020-02-29instead of the correct2020-03-01because our timezone is set toEurope/Stockholmand notUTC.The solution is to either set the timezone to
UTC(which of course is not an option), set the cast asdate:y-m-dor use the suggested upgrade guide solution of declaring our ownserializedDatemethod on the model.Is this really intended behaviour for
attributesToArray/toArrayregarding thedatecast?@markking79
This issue is tricky to understand, I tried to explain as best I could in the post https://github.com/laravel/framework/issues/31722#issuecomment-1131875330 above and more details in #42447
2022-04-05T11:52:53.000000Zis that it is a datetime + zone, i.e. UTC+0created_athas to show07:52:53, and we can see thatserializeDatedid not correct thatDon’t get me wrong. My concern is that this issue is hard to understand, so making it clear what does not work will better help everyone who reads this.
I was able to solve by adding the following method to my model…