【问题标题】:Web and Database server settings to get UTC timezone "right"获取 UTC 时区“正确”的 Web 和数据库服务器设置
【发布时间】:2016-11-29 23:56:25
【问题描述】:

我很难做到这一点:我们的服务器分布在十几个时区,Apache 和 MySQL 运行在全部或部分时区,MySQL 托管在 Amazon RDS 上。

我想知道“最佳实践”,或者如何配置每个 MySQL 和 PHP 安装,以便当从 PHP 向数据库中添加一行时,我确定那里的值实际上是事件发生时的 UTC 时间发生,无论发生时服务器位于 何处。在任何给定时区将其呈现给用户都不是问题 - 我只想知道 datetime 列实际上存储了发生某事的实际时间。

就像现在一样,由于预定事件等原因,Web 服务器被设置为任何本地时区,我不确定拼图的哪些部分使用了哪些设置从哪里得出所写的任何内容到数据库。

如果问题看起来不清楚,我深表歉意,在这一点上我不知道我不知道什么,因此获得一个精确的问题甚至具有挑战性。此外,我们所有的日期都作为 DateTime 字段在数据库中,因此无法存储时间戳。

【问题讨论】:

    标签: php mysql apache utc


    【解决方案1】:

    如果您限制自己使用 MySQL 的 DATE 和 DATETIME 类型,您可以在很大程度上忽略 MySQL 本身的时区问题。您想避免 MySQL 的 TIMESTAMP 类型,因为:

    MySQL 将 TIMESTAMP 值从当前时区转换为 UTC 进行存储,然后从 UTC 转换回当前时区进行检索。 (这不会发生在其他类型,例如 DATETIME。)默认情况下,每个连接的当前时区是服务器的时间。

    https://dev.mysql.com/doc/refman/5.7/en/datetime.html

    就读取/写入 DATETIME 值而言,您将准确返回您输入的内容,这很好。

    这给您留下了始终确保将 UTC 值写入数据库的问题。

    确保 PHP 使用 UTC 的最佳方法是使用 date_default_timezone_set() 在您的应用程序中显式设置它。这将确保像 date('Y-m-d H:i:s') 这样的调用会为您提供 UTC 值。它还将确保 (new \DateTime('now'))->getTimezone() 之类的内容将返回 UTC \DateTimeZone 实例。

    当然,您应该注意,当您存储从用户那里获取的日期/时间值时,事情会变得更加困难。在这些情况下,您需要以某种方式确定用户所在的时区,并在保留值之前处理转换为 UTC。假设您的用户有一些每个用户的时区设置,您基本上可以执行以下操作:

    /** @var \DateTimeZone $userTZ */
    $userTz = getUserTimezone();
    $dateTime = new \DateTime($user_submitted_date_string, $userTz);
    $dateTime->setTimezone(new \DateTime('UTC'));
    $dateTimeStr = $dateTime->format('Y-m-d H:i:s');
    

    【讨论】:

    • 这正是我一直在寻找的...“确保 PHP 使用 UTC...”并且我/我们可以在应用程序级别控制它。只要我知道 UTC 将进入数据库,其他一切都是小菜一碟....谢谢
    • 最后一个问题...似乎 MySQL 中的默认时区与任何 PHP 无关,除了使用 NOW()、CURDATE() 等的 SQL 之外。是这样吗?
    • @GDP - 我对做出这样的明确陈述持谨慎态度。但我会说是的。只要您避免依赖于 MySQL 内部默认时区设置的 MySQL 函数,就可以了。尤其是 INSERT/SELECT 行为与 VARCHAR 列的行为无法区分。
    • 这就是我需要的数据库洞察力...再次感谢...至少我知道我在地图上的位置并且现在可以绘制路线。
    【解决方案2】:

    非常简单,始终将 unix time 存储在数据库中(或者如果您希望 microtime 具有微秒精度)。然后,无论您的每个网络服务器的时区如何,如果其中两个同时收到请求,它将是保存在数据库中的相同整数值(数据库字段显然应该是一个 int (或 big int微时间))

    以及如何显示?使用 javascript 很容易。

    new Date(unix_timestamp);
    

    这会在用户的时区生成日期和时间。

    【讨论】:

    • 不能足够强烈地同意。唯一应该用字符串表示的地点日期和时间是在用户屏幕上的薄像素层上。
    • 我很抱歉...我会澄清所有数据都被存储为 MySQL 日期时间类型
    • 另外,不关心显示,这很“简单”。它知道 PHP 使用 date() 提出了什么与 MySQL 默认使用的时间戳与整个网络中各种服务器应用程序中设置的时区一致。
    • 是的,mysql 和 php(以及我使用过的许多其他语言)中的日期时间计算非常复杂。 unix 时代消除了所有的痛苦 + 处理时区的复杂性
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多