如何处理PHP + MySQL时区和MySQL GROUP BY [日期]查询?

时间:2013-02-06 09:09:44

标签: php mysql drupal datetime timezone

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

Drupal很好地处理了日期之外的日期:所有日期都存储为db中的UTC时间戳int,并且时区转换是通过每个用户配置文件中的时区设置按用户进行的,使用PHP 5的内置时区功能(因此每次运行PHP脚本时,脚本的时区都设置​​为当前用户的时区)。

只要我们坚持使用PHP,这一切都很好,很花哨,而且相当轻松。

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

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

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:只需从db中获取所有原始数据(有数十或数十万行),然后使用for循环在php中按日期对结果进行分组...这个解决方案似乎会显着增加资源,更慢,更有些荒谬。

  3. 所以我想我要问的是,我错过了什么吗?这里有最好的做法,我不知道吗?

    非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我会考虑这样的方法

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'));,然后再将其设置为已保存的值。