【问题标题】:Laravel saving data with Carbon::now() is formatted differently to created_atLaravel 使用 Carbon::now() 保存数据的格式与 created_at 不同
【发布时间】:2021-07-01 05:54:49
【问题描述】:

我正在使用 Laravel 项目和时区(我知道时区很痛苦),发生的事情是我的表中的一个自定义列,名为 last_checked 的列存储为timestamp 的格式似乎与 created_at 不同,这意味着我的时区解析根本没有解析用户时区的日期。

这就是我的意思...

存储记录时,我设置了日期和时间:

$uptimeMonitor = Monitors::where('id', $monitor['id'])
                           ->get()
                           ->first();

$uptimeMonitor->last_checked = Carbon::now();
$uptimeMonitor->save();

但是当我检索结果时,查看我的网络请求,我看到了这种格式:

2021-04-05 11:46:54

但是当我查看created_atupdated_at 列时,它们的格式如下:

2021-04-05T10:01:16.000000Z

所以这里的问题是,我在保存数据方面做错了什么?两种格式在数据库中的视觉显示似乎相同,但出于某种奇怪的原因,第一个示例未正确解析。

【问题讨论】:

  • 使用NOW()方法获取当前日期。
  • 这就是我目前正在做的事情?
  • Carbon::now() 不同于NOW() 方法
  • Carbon::now() 在这里完全没问题。因此,您的 PHP 配置(而不是 DB 配置)正在推动时间同步。 (所以你可以在单元测试中模拟它。)不要使用 SQL NOW(),这是错误的,不会解决你的问题。顺便说一句,UTC 应该是您的默认时区:config/app.php 和 DB 时区。

标签: php laravel date datetime php-carbon


【解决方案1】:

Carbon 使用默认的 DateTime PHP 对象,所以使用 date_default_timezone_set() 函数,例如:date_default_timezone_set('UTC');

或者你定义它AppServiceProviderApp/Providers/AppServiceProvider.php

public function boot()
{
    date_default_timezone_set('UTC');
}

或者你可以使用setTimezone的碳法

echo Carbon::now()->setTimezone('UTC')->format('H:i');

试试这个

$uptimeMonitor = Monitors::where('id', $monitor['id'])
                           ->get()
                           ->first();

$uptimeMonitor->last_checked = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s');
$uptimeMonitor->save();

请注意我的默认应用时区是UTC 只需找到您的默认时区 并将其设置在 `setTimezone('UTC');

【讨论】:

    【解决方案2】:

    您需要在 $casts 模型保护成员中添加所有日期时间属性:

    https://laravel.com/docs/8.x/eloquent-mutators#date-casting

    在您的数据库中一切正常,只是 Laravel 模型必须知道这是一个日期,以便在您的 JSON 中使用完整的 ISO-8601 字符串进行格式化。

    旁注,您仍然应该在 config/app.php 中将“UTC”作为默认值,它并不妨碍对特定情况进行任何时区处理,或者相反地处理用户时区。

    如果您的日期输出字符串默认为 GMT+1,则很可能是配置错误。

    【讨论】:

    • 我的 Laravel 配置现在是 Europe/London 的原因是因为它是 UTC,当英国夏令时开始时,数据库中的日期时间条目是一个小时,所以所有数据库值都会休息一小时
    • 那又怎样?这其实连个理由都没有。 UTC 是普遍表示时间的方式,因此任何系统/后端都应该使用它,而不是将您的应用程序绑定到它的城市时区,而它可能与它无关,当然也不是带有 DST 的时区,这将导致大量错误。你的 Laravel 的配置和你的数据库都应该是 UTC。但是您的问题仍然与时区无关,只是与转换/格式有关。我不知道您在等待什么样的奇迹,但以上就是您的解决方案。
    猜你喜欢
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2017-08-14
    相关资源
    最近更新 更多