我正在使用Drupal 7,PHP和MySQL,并试图从MySQL数据库中查询时区问题。
Drupal可以很好地处理日期:所有日期都存储为db中的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))
所以我们遇到了时区问题...
想到的可能解决方案:
硬编码时区:在我的模块中使用date_default_timezone_set()以确保PHP时区始终设置为系统时区(因此MySQL时区= PHP时区)。换句话说,分析时区将是硬编码的,而不是尊重查看分析的用户的时区。这确实不是理想的,因为我们希望多个时区的用户能够使用其时区访问分析。另外,date_default_timezone_set()似乎使Drupal搞砸了,因为它设置了整个脚本的时区,而不是仅仅在特定函数中。
忘记在查询中使用GROUP BY:只需从db中获取所有原始数据(有成千上万的行),然后使用for循环按日期在php中对结果进行分组...这种解决方案似乎会显着提高资源密集度,降低速度并有些荒谬。
所以我想我要问的是,我错过了什么吗?这里有我不知道的最佳实践吗?
非常感谢您的帮助!
最佳答案
我会考虑这样的方法
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'));
,然后再将其设置为已保存的值。