-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Closed
Description
- PHP version: 7.4.28
- Laravel version: 8.83.13
- MySQL version: 8.0.29-0ubuntu0.21.10.2
- MySQL Client version: mysqlnd 7.4.28
- databaseEngine version: mysql
Description:
Eloquent's fill(...)
should recognize timezones if provided.
Since Laravel 7+, toArray()
now returns datetimes in ISO-8601 format and that's ok.
However, ISO-8601 is not just time
, it is time
+ zone
.
See how Carbon adjusts it's zone (from +8 to 0) when parsing an ISO-8601
string
>>> $a = \Carbon\Carbon::now();
=> Carbon\Carbon @1652966760 {#6225
date: 2022-05-19 21:26:00.506481 Asia/Singapore (+08:00),
}
>>> $a = $a->parse("2022-04-05T11:52:53.000000Z");
=> Carbon\Carbon @1649159573 {#6230
date: 2022-04-05 11:52:53.0 +00:00,
}
>>> $a->getTimezone()
=> Carbon\CarbonTimeZone {#6231
timezone: +00:00,
}
>>>
Steps To Reproduce:
In contrast, when a model's created_at
is assigned an ISO-8601
string, it only assigns the time and drops the zone.
>>> $u = \App\Models\User::make()->fill(['created_at'=>'2022-04-05T11:52:53.000000Z']);
=> App\Models\User {#6225
created_at: "2022-04-05 11:52:53",
}
>>> $u->created_at->getTimezone()
=> Carbon\CarbonTimeZone {#6207
timezone: Asia/Singapore (+08:00),
}
>>>
Why it matters
toArray()
is a convenient way for movement of data out of the database- We ought to be able to import that same array back into the DB by using
fill(...)
- However, as illustrated above, the zone information is ignored and this causes problems for everyone except those on +00:00
- The solution should be as follows:
- Since an ISO-8601 string is provided, the time value should be shfited to match the DB's timezone, i.e. +08:00
- This shifted time is then filled into
created_at
- If a non ISO-8601 string is provided or a date/time without timezone is provided, then the current behavior makes sense, i.e. just write the value into
created_at
regardless of the DB's timezone
ert485
Metadata
Metadata
Assignees
Labels
No labels