1

我正在使用 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 中按日期对结果进行分组......这个解决方案似乎会资源密集度更高,速度更慢,而且有些荒谬。

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

非常感谢您的帮助!

4

1 回答 1

0

I would consider an approach such as this

SET time_zone = '+02:00';

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

And have

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

Since FROM_UNIXTIME bases it's time on time_zone, this should give desired result.

To undo the time_zone change afterwards, consider saving SELECT TIMEDIFF(NOW(), CONVERT_TZ(now(), @@session.time_zone, '+00:00')); first and then set it to saved value afterwards.

于 2013-02-06T09:52:16.717 回答