我正在使用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))
所以我们遇到了时区问题......
可能出现的解决方案:
对时区进行硬编码:在我的模块中使用date_default_timezone_set()以确保PHP时区始终设置为系统时区(因此MySQL时区= PHP时区)。换句话说,分析时区将是硬编码的,而不是尊重用户查看分析的时区。这真的不太理想,因为我们希望多个时区的用户能够使用他们的时区访问分析。此外,date_default_timezone_set()似乎搞乱了Drupal,因为它设置了整个脚本的时区,而不仅仅是在特定的函数中......
忘记在查询中使用GROUP BY:只需从db中获取所有原始数据(有数十或数十万行),然后使用for循环在php中按日期对结果进行分组...这个解决方案似乎会显着增加资源,更慢,更有些荒谬。
所以我想我要问的是,我错过了什么吗?这里有最好的做法,我不知道吗?
非常感谢您的帮助!
答案 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'));
,然后再将其设置为已保存的值。