没有不值得去解决的问题,也没有不值得去学习的技术!

在 Laravel 6 中,在不更改框架默认时区:Asia/Shanghai 的情况下,日期时间格式调整为 UTC

插入表中的数据为 UTC 时间,符合预期
1、之前的实现方案一,在数据库迁移文件中。$table->timestamps(); 相当于可空的 created_at 和 updated_at TIMESTAMP。


        Schema::create($tableName, function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });


2、在模型文件中,未设置 $timestamps ,默认为 true,Eloquent 自动管理这两个列:created_at 和 updated_at。 3、最终生成的值与东八区一致,因为当前时区设置为东八区。打印:config(‘app.timezone’) ,其值为:”Asia/Shanghai”。如图1
最终生成的值与东八区一致,因为当前时区设置为东八区。打印:config('app.timezone') ,其值为:"Asia/Shanghai"
图1
4、之前的实现方案二,数据库迁移文件无变化,但是模型文件中,$timestamps 属性设置为 false。然后在插入记录时,直接定义为:now()->utc()->timestamp。now 函数为当前时间创建一个新的 Illuminate\Support\Carbon 实例。其值相对于东八区时间,提前了 8 小时。如图2
之前的实现方案二,数据库迁移文件无变化,但是模型文件中,$timestamps 属性设置为 false。然后在插入记录时,直接定义为:now()->utc()->timestamp。now 函数为当前时间创建一个新的 Illuminate\Support\Carbon 实例。其值相对于东八区时间,提前了 8 小时。
图2
5、最终决定定义一个修改器,当我们尝试在模型上设置 created_at 和 updated_at 属性值时,该修改器将被自动调用。修改器会获取属性已经被设置的值,允许你修改并且将其值设置到 Eloquent 模型内部的 $attributes 属性上。


    /**
     * 设置创建时间
     *
     * @param $value
     * @return void
     */
    public function setCreatedAtAttribute($value)
    {
        $this->attributes['created_at'] = $this->transTz($value);
    }

    /**
     * 设置更新时间
     *
     * @param $value
     * @return void
     */
    public function setUpdatedAtAttribute($value)
    {
        $this->attributes['updated_at'] = $this->transTz($value);
    }

    /**
     * 转换时区
     *
     * @param $value
     * @return string
     */
    private function transTz($value = null): string
    {
        return $value instanceof Carbon
            ? $value->utc()->toDateTimeString()
            : ($value ?: now()->utc()->toDateTimeString());
    }


6、插入表中的数据为 UTC 时间,符合预期。如图3
插入表中的数据为 UTC 时间,符合预期
图3
7、但是,当使用 push() 方法时,日期时间仍然为:”Asia/Shanghai”。总记 3 条 SQL,前 2 条 SQL 使用 UTC ,第 3 条 SQL 使用的 Asia/Shanghai。如图4
但是,当使用 push() 方法时,日期时间仍然为:"Asia/Shanghai"。总记 3 条 SQL,前 2 条 SQL 使用 UTC ,第 3 条 SQL 使用的 Asia/Shanghai
图4


$this->themeInstallationTask->themeInstallation->processing = ThemeInstallation::PROCESSING_FALSE;
$this->themeInstallationTask->themeInstallation->processing_failed = ThemeInstallation::PROCESSING_FAILED_FALSE;

$this->themeInstallationTask->themeInstallationVersionPreset->processing = ThemeInstallationVersionPreset::PROCESSING_FALSE;
$this->themeInstallationTask->themeInstallationVersionPreset->processing_failed = ThemeInstallationVersionPreset::PROCESSING_FAILED_FALSE;

$this->themeInstallationTask->processing = ThemeInstallationTask::PROCESSING_FALSE;
$this->themeInstallationTask->processing_failed = ThemeInstallationTask::PROCESSING_FAILED_FALSE;

$this->themeInstallationTask->push();




update
  `theme_installation_task`
set
  `processing` = 0,
  `theme_installation_task`.`updated_at` = '2022-06-21 10:02:50'
where
  `id` = 18;

update
  `theme_installation`
set
  `processing` = 0,
  `theme_installation`.`updated_at` = '2022-06-21 02:02:50'
where
  `id` = 18;

update
  `theme_installation_version_preset`
set
  `processing` = 0,
  `theme_installation_version_preset`.`updated_at` = '2022-06-21 02:02:50'
where
  `id` = 18;


8、原因应该在于 $value 并非 Carbon 的实例,因而原样返回 $value。需要将 $value 转换为 Carbon 的实例。


/**
     * 转换时区
     *
     * @param $value
     * @return string
     */
    private function transTz($value = null): string
    {
        if (is_null($value)) {
            return now()->utc()->toDateTimeString();
        }
        return ($value instanceof Carbon) ? $value->utc()->toDateTimeString() : Carbon::parse($value, 'utc')->toDateTimeString();
    }


9、当使用 push() 方法时,日期时间已经为 UTC 了。符合预期。如图5 10、但是,使用 update() 方法时,日期时间仍然为:”Asia/Shanghai”
<pre class="wp-block-syntaxhighlighter-code">

ThemeInstallation::where('wp_theme_id', '<>', $id)->update(['role' => ThemeInstallation::ROLE_UNPUBLISHED]);

</pre>
<pre class="wp-block-syntaxhighlighter-code">

update
  `theme_installation`
set
  `role` = 'unpublished',
  `theme_installation`.`updated_at` = '2022-06-21 13:38:36'
where
  `wp_theme_id` <> 195

</pre>
11、决定在更新时手动指定 updated_at。符合预期。
<pre class="wp-block-syntaxhighlighter-code">

ThemeInstallation::where('wp_theme_id', '<>', $id)->update(['role' => ThemeInstallation::ROLE_UNPUBLISHED, 'updated_at' => now()->utc()->toDateTimeString()]);

</pre>
<pre class="wp-block-syntaxhighlighter-code">

update
  `theme_installation`
set
  `role` = 'unpublished',
  `theme_installation`.`updated_at` = '2022-06-21 07:39:46'
where
  `wp_theme_id` <> 195

</pre>

PHP / Laravel / Yii2 老项目维护与长期技术支持

如果你的 PHP / Laravel / Yii2 项目已经上线,但遇到原开发离职、Bug 长期无人修复、接口不稳定、性能下降、代码难以接手等问题,可以联系我做一次远程技术排查。

适合以下情况:
✅ 老旧 PHP 系统无人维护
✅ Laravel / Yii2 项目 Bug 修复
✅ 后台管理系统小功能迭代
✅ RESTful API 接口排查
✅ MySQL / Redis / Nginx 性能问题
✅ 长期远程兼职维护

可先从一次小问题开始:
✅ 线上报错排查
✅ 接口异常分析
✅ 慢查询与性能瓶颈定位
✅ 代码结构初步评估
✅ 部署环境与日志检查

如需咨询,请联系我,并注明:PHP 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理