我正在使用队列工作器处理 Laravel 应用程序,它刚刚开始失败并向日志抛出持续的异常流。这是其中之一:
SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2019-03-10 02:00:39' for column 'updated_at' at row 1 (SQL: update `videos` set `updated_at` = 2019-03-10 02:00:39 where `id` = 30860)
Run Code Online (Sandbox Code Playgroud)
需要注意的几点:
updated_at字段由 Laravel 默认值管理,日期格式没有任何自定义发生git checkout .并composer install确保没有任何库文件以某种方式更改或损坏(没有更改)2019-03-10 02:00:39(UTC),即当地时间晚上 8 点明尼苏达州 2019 年夏令时将于 3 月 10 日星期日凌晨 2:00 开始
- 谷歌
我在谷歌上能找到的一切都与使用明显错误的时间格式的人有关,所以这并没有帮助我弄清楚。
我觉得在夏令时应该在美国中部时间02:00 开始的同一天02:00 UTC开始的错误之间有太多的巧合,但我不知道为什么会这样当时间戳由框架管理并在保存之前转换为 UTC 时抛出此错误(并且 UTC 不会因夏令时而改变)。
MySQL 5.5.45
Laravel 5.7.28
nesbot/carbon 1.36.2
PHP 7.2.7
配置/数据库.php:
'mysql' => [
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
Run Code Online (Sandbox Code Playgroud)
什么可能导致日期值被识别为无效?
编辑:我确定这绝对是夏令时错误,因为时钟向前跳过 1 小时,02:00 和 03:00 之间的时间在美国中部时间无效。我不明白的是为什么设置为 UTC 的应用程序上的 TIMESTAMP 字段会抛出错误?UTC 如何受到夏令时的影响,当时间戳由框架 (Laravel+Carbon) 管理时,我该怎么做才能防止这种情况发生?
Tra*_*itz 12
我发现问题是由于我的 MySQL 服务器的time_zone设置被设置为SYSTEM(并且我的系统是美国中央)。Laravel 提供的时间戳已转换为 UTC,但由于time_zone设置,我的数据库将它们解释为 US Central 。MySQL 在内部实际上将时间再次转换为“真实的”UTC unix 时间戳表示(这将是不正确的,因为它被时区偏移),即使它们在每个查询中似乎已经是 UTC,因为它们也被转换回来再次到美国中央阅读(我知道正确)。
因此,在当地时间 20:00:39(晚上 8:00),我的 Laravel UTC 时间戳是 02:00:39。MySQL 将这些时间解释为美国中部时间,并且由于时间介于 02:00 和 03:00 之间(这是美国中部时钟向前跳的时间),因此该时间无效。
Laravel 应用程序的最佳解决方案是强制每个数据库连接使用+00:00时区(或您在 中设置的应用程序时区config/app.php),这样就不会发生二次转换。这可以在config/database.php:
'mysql' => [
// ...
'timezone' => '+00:00'
],
Run Code Online (Sandbox Code Playgroud)
这样,如果您的数据库服务器配置的时区与您的 Laravel 应用程序不同,您就不会受到数据库服务器的支配。另一种选择是更改数据库的time_zone设置,但是如果您更改主机或出于任何原因需要重建服务器(并且不要再次正确配置时区),或者影响其他数据库上的其他数据库,那么您仍然面临错误再次发生的风险服务器。
重要说明:由于所有以前的时间戳都由 MySQL 在内部从配置的时区偏移到 UTC unix 时间戳(这也是错误的,因为记录已经是 UTC),因此可能需要运行数据迁移以更正旧时间戳。我没有进一步调查,因为对于我的应用程序,旧时间戳是否错误几个小时并不重要。
| 归档时间: |
|
| 查看次数: |
8264 次 |
| 最近记录: |