【问题标题】:Laravel timestampTz columns have the wrong timezoneLaravel timestampTz 列的时区错误
【发布时间】:2021-03-18 00:02:12
【问题描述】:

我正在使用带有 Laravel 8.4.4 的 Postgres 13

为定义为强制转换为 datetime 的 Eloquent 模型属性设置 Unix 时间戳 1607207809,我们得到正确的 Carbon 时间 2020-12-05 22:36:49.0 +00:00

但是,保存此模型实例(其中该列在迁移中定义为 timestampTz 列)会导致 2020-12-05 22:36:49-08 被保存。这不是正确的时区,导致时间不正确。

config/app.php 中,时区设置为UTC。我的计算机的时区是太平洋时间,所以它似乎以某种方式优先。任何想法为什么?

我本来希望使用 Carbon 编码的时区保存时间戳,但显然不是?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    我发现的最佳解决方案是在模型上定义$dateFormat = 'Y-m-d H:i:s P',同时转换为日期时间。

    不应使用自定义 Cast 类 (https://laravel.com/docs/8.x/eloquent-mutators#custom-casts),因为在创建新对象时,created_atupdated_at 属性尚未设置。

    在未定义 $dateFormat 的情况下,传递给 created_atupdated_at 的 Cast 类设置器的 $value 参数的格式为“Y-m-d H:i:s”。

    如果您的数据库服务器设置为与您的应用程序相同的时区,这不是问题,但会发生错误。

    【讨论】:

      【解决方案2】:

      您可以通过date_default_timezone_set函数设置时区来设置整个laravel应用程序使用的时区。

      AppServiceProvier添加这段代码

      public function boot(){
           date_default_timezone_set('Pacific/xxxxxx');
      }
      

      在此处查看您的时区名称Pacific Zone

      【讨论】:

      • 这违背了使用 timestamptz 的目的,因为 Carbon 对象可能被初始化为不同的时区。我想要的是让 Carbon 对象成为有关时区的真相的来源。
      • 此外,由于 Postgres 服务器时区可能与 Laravel 应用程序不同,因此在插入时仍然容易出现问题。通过在插入查询中包含 Carbon 时区偏移量,我相信所有可能导致意外时间戳突变的冲突都可以避免。确保一切安全可能是错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 2016-04-15
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多