mysql - Laravel SQLSTATE[22007] : Invalid datetime format: 1292 Incorrect datetime value: '2019-03-10 02:00:39' for column 'updated_at' (daylight savings?)

标签 mysql laravel

我正在使用队列工作程序开发 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) 

需要注意的几点:

  • 时间戳似乎是正确的格式
  • 该列是 MySQL TIMESTAMP 类型(可为空),使用 InnoDB
  • updated_at 字段由 Laravel 默认值管理,日期格式没有发生任何自定义
  • 我没有使用任何日期更改器(mutator),或任何会在保存前更改值的东西
  • 此代码已运行数周,没有出现任何问题
  • 最近没有更改代码
  • 我执行了 git checkout .composer install 以确保所有库文件均未更改或以某种方式损坏(没有更改)
  • 该错误首次出现于 2019-03-10 02:00:39 (UTC),即本地时间晚上 8 点(中部时间)

Daylight saving time 2019 in Minnesota will begin at 2:00 AM on Sunday, March 10

-- Google

我在谷歌上找到的所有内容都与某人使用明显错误的时间格式有关,所以这并没有帮助我弄清楚。

我觉得夏令时应该在美国中部时间 02:00 开始的同一天从 02:00 UTC 开始的错误之间有太多的巧合,但我不知道为什么当时间戳由框架管理并在保存之前转换为 UTC 时会抛出此错误(并且 UTC 不会因夏令时而改变)。

MySQL 5.5.45
Laravel 5.7.28
nesbot/carbon 1.36.2
PHP 7.2.7

配置/database.php:

'mysql' => [
    
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],

什么可能导致日期值被识别为无效?

编辑:我确定这绝对是夏令时错误,因为时钟向前跳 1 小时,并且 02:00 到 03:00 之间的时间在美国中部时间中无效。我不明白的是为什么应用程序上设置为 UTC 的 TIMESTAMP 字段会抛出错误? UTC 如何受到夏令时的影响?当时间戳由框架(Laravel+Carbon)管理时,我该如何防止这种情况发生?

最佳答案

我发现问题是由于我的 MySQL 服务器的 time_zone设置被设置为 SYSTEM (我的系统是美国中央系统)。 Laravel 提供的时间戳已转换为 UTC,但由于 time_zone,我的数据库将它们解释为美国中部时间。环境。实际上,MySQL 在内部将时间再次转换为“真正的”UTC unix 时间戳表示(这将是不正确的,因为它被时区偏移),即使它们在每个中都已经是 UTC。查询,因为它们也会再次转换回美国中部进行阅读(我知道是对的)。

因此,在本地时间 20:00:39 (8:00 PM),我的 Laravel UTC 时间戳是 02:00:39。 MySQL 将这些时间解释为美国中部时间,并且由于时间在 02:00 到 03:00 之间(这是美国中部时钟向前跳动的时间),因此该时间无效。

Laravel 应用程序的最佳解决方案是强制每个数据库连接使用 +00:00时区(或者您在 config/app.php 中设置为应用程序时区的任何内容),因此不会发生二次转换。这可以在 config/database.php 中完成:

'mysql' => [
    // ...

    'timezone'  => '+00:00'
],

这样,如果数据库服务器配置的时区与 Laravel 应用程序不同,您就不会受到数据库服务器的支配。另一个选项是更改数据库的 time_zone设置,但是如果您更改主机或出于任何原因需要重建服务器(并且不要再次正确配置时区),或者影响服务器上的其他数据库,您仍然面临错误再次出现的风险。

重要说明:由于 MySQL 内部将所有先前的时间戳从配置的时区偏移到 UTC unix 时间戳(这又是错误的,因为记录已经是 UTC),因此可能需要运行数据迁移更正旧的时间戳。我没有进一步调查,因为对于我的应用程序来说,旧时间戳是否错误几个小时并不重要。

关于mysql - Laravel SQLSTATE[22007] : Invalid datetime format: 1292 Incorrect datetime value: '2019-03-10 02:00:39' for column 'updated_at' (daylight savings?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55084109/

相关文章:

laravel - 无法在 PhpStorm 10.0.3 上添加 Artisan 命令行工具

php - 如何解决访问 laravel 路由时出现 CORS 错误

php - 从 Carbon\Carbon 对象中获取日期

php - 将更改上传到模板文件时 Laravel 错误 500

mysql - 为什么我共同的好友查询这么慢?

mysql - 如何使用具有多个输入的表单更新 mysql 记录,但仅使用输入的值更新输入

mysql - 将 CSV 或 XML 导入 MySQL

python - 将unicode象形文字保存到mysql

php - 根据键值将数组插入mysql

php - 503后端提取失败-Varnish缓存服务器Laravel