php - 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' 也不能在这种情况下使用。
解决方案
以 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();
}
此选项假定您将用户的时区存储在数据库的另一个字段中。
推荐阅读
- azure - Xamarin Mobile 使用的 ASP.Net Core Web API
- sql - 如何在sas proc sql中查询多个where条件
- python - 如何在保持值顺序的情况下将字典转换为数据框?
- matrix - Prolog中的乘法矩阵
- flutter - Flutter SQFlite 按整数ID列表删除多个
- node.js - NPM 可以在安装包之前显示包的年龄吗?
- ruby-on-rails - 尝试运行捆绑安装时出现openssl构建错误
- mysql - MySQL循环不同的结果
- python - 如何使用 tkinter 在 python 中进行追逐按钮游戏?
- html - 具有弹性和媒体查询的响应式设计