【问题标题】:How to deal with PHP + MySQL timezones and MySQL GROUP BY [date] queries?如何处理 PHP + MySQL 时区和 MySQL GROUP BY [date] 查询?
【发布时间】:2013-01-21 10:12:12
【问题描述】:

我正在使用 Drupal 7、PHP 和 MySQL,并试图在从 MySQL 数据库查询时解决时区问题。

Drupal 可以很好地处理日期:所有日期都以 UTC 时间戳 int 的形式存储在数据库中,并且使用 PHP 5 的内置功能,通过每个用户配置文件中的时区设置在每个用户的基础上进行时区转换时区功能(因此每次运行 PHP 脚本时,脚本的时区都会设置为当前用户的时区)。

所以只要我们坚持 PHP,这一切都很好,花花公子而且相当轻松。

当我们引入 MySQL 时,事情开始变得棘手,因为似乎没有办法将当前 PHP 脚本时区与给定的 MySQL 查询完美同步。似乎最佳实践要求在 PHP 中处理所有时区转换:只在数据库中查询原始时间戳,然后根据需要在 PHP 中进行转换。

这在大多数情况下似乎是合理的(即使有时会慢一点),但是我应该如何处理 MySQL GROUP BY [date] 查询?例如,我正在构建一个模块来处理分析,并且经常想做以下事情:

GROUP BY YEAR(FROM_UNIXTIME(u.created)), MONTH(FROM_UNIXTIME(u.created))

所以我们遇到了时区问题...

想到的可能解决方案:

  1. 硬编码时区:在我的模块中使用 date_default_timezone_set() 以确保 PHP 时区始终设置为系统时区(因此 MySQL 时区 = PHP 时区)。换句话说,分析时区将被硬编码,而不是尊重查看分析的用户的时区。这确实不理想,因为我们希望多个时区的用户能够使用他们的时区访问分析。此外, date_default_timezone_set() 似乎把 Drupal 搞砸了,因为它为整个脚本设置时区,而不是仅仅在一个特定的函数中......

  2. 忘记在查询中使用 GROUP BY:只需从数据库中获取所有原始数据(可能有数万行或数十万行),然后使用 for 循环在 php 中按日期对结果进行分组...这个解决方案似乎会占用更多的资源,更慢,而且有点荒谬。

所以我想我要问的是,我错过了什么吗?这里有我不知道的最佳实践吗?

非常感谢您的帮助!

【问题讨论】:

    标签: php mysql drupal datetime timezone


    【解决方案1】:

    我会考虑这样的方法

    SET time_zone = '+02:00';
    

    http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

    还有

    GROUP BY FROM_UNIXTIME(u.created, '%Y-%m');
    

    由于FROM_UNIXTIME 是基于time_zone 的时间,这应该会产生预期的结果。

    若要在之后撤消 time_zone 更改,请考虑先保存 SELECT TIMEDIFF(NOW(), CONVERT_TZ(now(), @@session.time_zone, '+00:00'));,然后再将其设置为保存的值。

    【讨论】:

    • 感谢罗宾的想法。 MySQL SET time_zone 的问题在于范围是针对整个客户端连接,而不是针对特定查询,据我所知,新时区会影响每个 Drupal 数据库查询。有没有办法解决这个问题?
    • Get 并保存默认的 time_zone 并在之后运行查询,将其重置为以前的值。
    • 这个解决方案对我来说似乎非常老套。如果我错了,请纠正我,但由于每分钟可能有数千次页面查看,似乎无法保证在更改和重置时区之间不执行其他查询。当然,无论如何我都很感谢你的建议......不像我想出了更好的主意......
    • 据我所知,它只会影响当前的执行。并且一次执行 1 个查询。因此,我认为这里没有问题。 Per-connection time zones. Each client that connects has its own time zone setting, given by the session time_zone variable.
    • 感谢罗宾的帮助。不过,我仍然对此保持警惕......我想我不确定数据库“连接”何时开始和结束,就 Drupal 而言......你有这方面的知识吗,你能指出任何文件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    相关资源
    最近更新 更多