简体   繁体   English

PHP & MySQL DateTime - 时区处理

[英]PHP & MySQL DateTime - Timezone Handling

I want to store a DateTime value in my database ( MySQL 5.7 ).我想在我的数据库中存储一个DateTime值( MySQL 5.7 )。 I am trying to figure out the best way to handle time zones.我试图找出处理时区的最佳方法。 From a glance it seems that MySQL only takes DateTime in the format of Ymd H:i:s which leaves out any Timezone info.乍一看,MySQL 似乎只采用Ymd H:i:s格式的DateTime ,而忽略了任何时区信息。 There is however the Timestamp data type that allows you to give a UTC string.然而, Timestamp数据类型允许您提供 UTC 字符串。 Unfortunately, this is only accepted until the date is greater than the year 2038.不幸的是,这仅在日期大于 2038 年之前被接受。

The situation I have in mind is something like the following.我想到的情况如下所示。 Lets say our application server and MySQL server are in one timezone.假设我们的应用服务器和 MySQL 服务器在一个时区。 A user in that timezone creates a file that is then indexed in the database.该时区的用户创建一个文件,然后在数据库中建立索引。 A different user in a different timezone wants to view this file and some meta information within the application.不同时区的不同用户想要查看此文件和应用程序中的一些元信息。 I want to show the correct time that the file was created relative to this users timezone.我想显示相对于该用户时区创建文件的正确时间。

How would I properly go about storing this date and time?我将如何正确 go 关于存储此日期和时间? I understand there may need to be some manipulation with JavaScript's toLocaleString() .我知道可能需要对 JavaScript 的toLocaleString()进行一些操作。

Edit: It looks like this has been addressed (for the most part) in MySQL 8 but I am looking for a 5.7 compatible solution .编辑:看起来这个问题(大部分)在 MySQL 8 中得到了解决,但我正在寻找一个5.7 兼容的解决方案

As of MySQL 8.0.19, you can specify a time zone offset when inserting TIMESTAMP and DATETIME values into a table.从 MySQL 8.0.19 开始,您可以在将 TIMESTAMP 和 DATETIME 值插入表时指定时区偏移量。 The offset is appended to the date part of a datetime literal, with no intravening spaces, and uses the same format used for setting the time_zone system variable, with the following exceptions:偏移量附加到日期时间文字的日期部分,没有内部空格,并使用与设置 time_zone 系统变量相同的格式,但以下情况除外:

For hour values less than than 10, a leading zero is required.对于小于 10 的小时值,需要前导零。

The value '-00:00' is rejected.值“-00:00”被拒绝。

Time zone names such as 'EET' and 'Asia/Shanghai' cannot be used;不能使用“EET”和“Asia/Shanghai”等时区名称; 'SYSTEM' also cannot be used in this context. 'SYSTEM' 也不能在这种情况下使用。

Store all your data in UTC time.以 UTC 时间存储所有数据。 It gives you the greatest flexibility when dealing with users in multi-regions and/or multi-servers/databases.在与多区域和/或多服务器/数据库中的用户打交道时,它为您提供了最大的灵活性。

  • If you are using JavaScript, you can pull a user's timezone by using如果您使用的是 JavaScript,您可以通过使用拉取用户的时区
Intl.DateTimeFormat().resolvedOptions().timeZone

From here, you would reformat the datetime string using the user's timezone into account.从这里开始,您将使用用户的时区重新格式化日期时间字符串。

  • If you are using an ORM like Eloquent in Laravel (PHP), you can adjust the a datetime field on the fly by declaring a method in your model. If you are using an ORM like Eloquent in Laravel (PHP), you can adjust the a datetime field on the fly by declaring a method in your model. For example, to change the 'created_at' field:例如,要更改“created_at”字段:
    public function getCreatedAtAttribute($value)
    {
        return Carbon::createFromTimestamp(strtotime($value))
            ->timezone('America/Los_Angeles')
            ->toDateTimeString();
    }

This option assumes you store the user's timezone in another field in your database.此选项假定您将用户的时区存储在数据库的另一个字段中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM