【问题标题】:Carbon::now displaying wrong time unless formattedCarbon::now 显示错误的时间,除非格式化
【发布时间】:2021-09-19 18:07:35
【问题描述】:

我对从数据库返回的时间有疑问,一切都是过去 2 小时。

我已经对此问题进行了一段时间的故障排除,并检查了以下内容:

/etc/php.ini 只是使用中的ini,并且有date.timezone = Europe/Amsterdam.(也重启了apache)

Laravel 的 app.php 配置有 'timezone' => 'Europe/Amsterdam'

我跑了config:clearconfig:cache

我能够将问题归结为 Carbon。

我有一条简单地返回 Carbon::now() 的路线,它显示 2021-07-09 10:58:31.874837Z(提前 2 小时)

如果我将代码修改为Carbon::now()->format("Y-m-d H:i:s"),它会返回2021-07-09 12:58:31,这是正确的时间。

如果我运行 tinker,然后运行Carbon/Carbon::now(),它会直接显示正确的时间(本地在 Win 10 和 centos 服务器上)

我不确定为什么 carbon 在格式化时会显示不同的时间,我是不是在某处遗漏了配置?

提前谢谢你。

注意:

如果我使用 tinker,我会从我的数据库(时区为 CEST)和 Carbon::now() 获得正确的时间

【问题讨论】:

    标签: php laravel laravel-8 php-carbon php-8


    【解决方案1】:

    我有一条只返回 Carbon::now() 的路线,它显示 2021-07-09 10:58:31(提前 2 小时)

    如果我将代码修改为 Carbon::now()->format("Y-m-d H:i:s") 它将返回 2021-07-09 12:58:31,这是正确的时间。

    什么是第一句中的“显示”,因为对象不可能具有与使用format("Y-m-d H:i:s") 格式化时看到的不同的时区或值

    2021-07-09 10:58:31这里是日期时间转换成UTC的结果。

    所以我猜你说的是 JSON 输出,而你看到的实际上是 2021-07-09T10:58:31Z 而不是 2021-07-09 10:58:31,在这种情况下是正确的,这里的 Z 非常重要,要保持它的意思是“Zulu = GMT”,并允许 JSON 阅读器(例如网络浏览器)在地球上的任何地方构建正确的日期,而如果返回 2021-07-09 12:58:31,则阅读器将不知道它是什么时区。

    【讨论】:

    • 老实说,正如您在另一条评论中提到的那样,我确实在解释中犯了一个错误。它确实在末尾添加了Z(编辑了问题)我不知道这与webbrowser/json-reader通信。谢谢你的信息,这真的很有帮助。现在我想我只需要设置 chrome 就可以正确地进行格式化。
    【解决方案2】:

    你打开

    我对从我的数据库返回的时间有疑问,一切都是过去 2 小时。

    您的数据库可能是这里的关键:存储在那里的数据是否带有时区?是否预计在特定时区?数据库可能会返回 UTC,它正好是夏季 CET(阿姆斯特丹时间)的 2 小时。您的应用程序将此时间解释为 CET。因此,时间落后了 2 小时

    我的建议是不要在技术层的任何地方都使用时区,而只在 UI 中格式化为用户的时区。例如。让您的所有服务器仅在 UTC 上运行。以 UTC 存储时间。在 UTC 中计算您需要的任何内容。并且为了显示,转换为当前用户的首选时区。

    该建议可能正是您遇到的问题:您的数据库仅存储 UTC 时间,您将其解释为 CET。不要那样做。这将导致今年秋季对夏令时的下一次更改造成混乱。

    添加:

    即使(或特别是)在您的说明之后,我仍然坚持我在上面写的内容:所有您的技术基础设施纯粹在 UTC 上工作,始终时间>。这意味着直到最后一刻,将时间转换为用户的首选时区,才会有任何转换。或者如果有,找到罪魁祸首是微不足道的。当您经常在所有操作中涉及时区数学(除了到/从 UTC 转换)时,所有的地狱都会失败。尤其是夏令时前后变化(发生在不同地区的不同日期,以及两个半球的不同方向)

    【讨论】:

    • 感谢您的回复。我在我的问题中添加了一条注释,指出我的数据库具有“正确的”时区 (CEST),并且通过修补程序,我从我的数据库和 Carbon::now() 获得了正确的时间。只有当代码通过网络服务器而不是通过 CLI 运行时才会失败。似乎网络服务器出于某种原因误解了时间,但我看不出在哪里。我想知道您保留所有 UTC 的解决方案是否可以充分解决问题,或者我会遇到更多问题。
    • 看我的回答,我敢打赌你关于“Carbon::now() 的陈述,它显示 2021-07-09 10:58:31”实际上是不完整的,你在说什么输出?视图、JSON、纯文本响应?每个人都可以以不同的方式转换/格式化日期,这很重要,那么日期的完整输出是什么?您确定"2021-07-09 10:58:31" 是您作为输出得到的确切字符串吗?因为我看不出你怎么会从Carbon::now() 得到它,所以我怀疑你在描述这个问题时采取了捷径。
    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 2018-06-27
    • 2018-01-10
    • 2019-07-15
    • 2011-04-22
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多