首页 > 解决方案 > PHP & MySQL DateTime - 时区处理

问题描述

我想DateTime在我的数据库中存储一个值(MySQL 5.7)。我试图找出处理时区的最佳方法。乍看之下,MySQL 似乎只采用了忽略任何时区信息DateTime的格式。Y-m-d H:i:s但是,有一种Timestamp数据类型允许您提供 UTC 字符串。不幸的是,这仅在日期大于 2038 年之前被接受。

我想到的情况如下所示。假设我们的应用服务器和 MySQL 服务器在一个时区。该时区的用户创建一个文件,然后在数据库中建立索引。不同时区的不同用户想要查看此文件和应用程序中的一些元信息。我想显示相对于该用户时区创建文件的正确时间。

我将如何正确存储此日期和时间?我知道可能需要对 JavaScript 的toLocaleString().

编辑:看起来这个问题已经在 MySQL 8 中得到解决(大部分),但我正在寻找一个兼容 5.7 的解决方案

从 MySQL 8.0.19 开始,您可以在将 TIMESTAMP 和 DATETIME 值插入表时指定时区偏移量。偏移量附加到日期时间文字的日期部分,没有内部空格,并使用与设置 time_zone 系统变量相同的格式,但以下情况除外:

对于小于 10 的小时值,需要前导零。

值“-00:00”被拒绝。

不能使用“EET”和“Asia/Shanghai”等时区名称;'SYSTEM' 也不能在这种情况下使用。

标签: phpmysqldatetime

解决方案


以 UTC 时间存储所有数据。在与多区域和/或多服务器/数据库中的用户打交道时,它为您提供了最大的灵活性。

  • 如果您使用的是 JavaScript,则可以通过使用拉取用户的时区
Intl.DateTimeFormat().resolvedOptions().timeZone

从这里开始,您将使用用户的时区重新格式化日期时间字符串。

  • 如果你在 Laravel (PHP) 中使用像 Eloquent 这样的 ORM,你可以通过在模型中声明一个方法来动态调整日期时间字段。例如,要更改“created_at”字段:
    public function getCreatedAtAttribute($value)
    {
        return Carbon::createFromTimestamp(strtotime($value))
            ->timezone('America/Los_Angeles')
            ->toDateTimeString();
    }

此选项假定您将用户的时区存储在数据库的另一个字段中。


推荐阅读