如何正确设置mysql时区


How to correctly set mysql timezone

我有一个关于mysql时区的奇怪问题。

在我的网站配置文件中,我有这一行设置时区:

mysql_query("SET SESSION time_zone = '$offset';"); // Offset is properly calculated, no worries about that

有趣的是,如果我在这行后面再加一行,像这样:

$q = mysql_query("SELECT NOW() as now");
$row = mysql_fetch_array($row);
echo $row["now"];

执行该代码后,时间显示正确。

但是,在其他一些查询中,我在表中插入列名为date的行,默认为CURRENT_TIMESTAMP。

行插入方式如下:

INSERT INTO `sessions` (`user_id`) VALUES `1`

(会话表有一个date列,默认为CURRENT_TIMESTAMP)

但是插入到DB中的值仍然指向服务器的时区:((

)

有什么想法吗?

您必须了解MySQL维护多个时区设置:

  • 系统时区(基本上是操作系统设置的时区)
  • 服务器时区(MySQL使用的时区)
  • 客户端时区(每次连接使用的会话时区)

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

日期/时间值有两种存储方式:

  • 所有基于unix时间戳的值总是以UTC存储。在存储和读取它们时,它们在内部动态地从客户机时区转换为客户机时区。NOW()和CURTIME()函数也是如此,因为它们是基于时间戳的。
  • DATE, TIME和DATETIME列(以年-月-日-时-分-秒格式存储其值)不受时区设置的影响,并且永远不会转换。

从上面应该可以清楚地看出,当您从基于unix时间戳的列中读取时看到的值不一定是真正存储在DB中的值。它们使用服务器时区和客户端时区进行转换。如果你不了解机制的细节,结果可能会令人困惑。

对于第一个测试,尝试通过执行

找出每个客户端程序中的当前设置。
SELECT @@global.time_zone, @@session.time_zone;

全球时区将始终相同。但是会话时区可能因客户端应用程序而异,并且会改变读和写操作的结果。