您在MySQL服务器上运行了此时间诊断查询.
select @@time_zone, now(), utc_timestamp()
从您的本地时间和utc时间可以清楚地看到,您服务器的系统时区设置为“加拿大/山地”,而MySQL服务器软件没有自己的时区设置.
如果您拿起表并将它们原封不动地移到附近的某个时区中的服务器,则可以随时更新软件以发出命令
set time_zone = 'Canada/Mountain';
在您从软件进行连接之后.这将使您的新MySQL连接的行为像您当前的时区一样.如果您拥有MySQL服务器,则可以根据此页面上的说明设置其默认时区. http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
现在,这里是有关时间数据类型的故事. DATE,TIME和DATETIME都是时区忽略的.保存日期/时间值后,即使您更改了时区设置,也将获得相同的值.
TIMESTAMP数据类型是时区敏感的.这些数据项始终存储在UTC, also known as Z, time中,以前称为格林威治标准时间.它们在存储时总是转换为UTC,而在检索时总是转换回.
用于获取当前日期和时间(NOW()和朋友)的builtin functions是时区敏感的.他们将在当地时间产生值.例外情况是三个以UTC_开头的函数,它们以UTC时间产生值.
许多MySQL多时区应用程序都遵循以下操作准则:
>向每个用户询问用户偏好的时区,或从有关该用户的其他个人数据中找出该时区. (电话已从网络向电话提供了此信息.)代表用户将其存储为zoneinfo-friendly时区描述符(“美国/纽约州”,“加拿大/山地”,“欧洲/维也纳”等).
>在代表用户建立MySQL会话后,使用设置的time_zone查询(如上所示)设置用户的时区.您应该在连接操作之后立即执行此操作.
>将用户的日期和时间存储到TIMESTAMP数据类型中.它们将在存储时转换为UTC.
>根据需要检索它们.他们将转换回当地时间.
想法是您用户的时区是其上下文的一部分.这样做很好,因为如果用户A在温哥华,而用户B在哈利法克斯,并且由于某种原因,用户B查看了用户A的时间数据,那么它将自动或多或少地显示给大西洋时间B.
这也很好,因为它可以透明地处理日光到标准时间变化的全球变化.去年夏天的时间戳将显示在去年夏天的本地时间.
许多供全球使用的服务器管理器将其系统服务器时间或MySQL默认时区设置为UTC. (您没有.)
处理所有这一切的另一种方法是开始的方式.选择一个时区并存储相对于该时区的时间戳.在这种情况下,最好选择一个不在夏令时和标准时间之间交替的时区.然后,将时间存储到数据库中时,显式转换.您可以通过执行以下操作来存储来自渥太华用户的时间.
INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)
您将以相同的方式获得价值.这容易出错,但是您可以使其正常工作.
最后,您可以自己进行转换.
如果您想知道某个任意时区和UTC之间有多少分钟的偏移量,请尝试这两个查询.
set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());
在一年中的这个时候,该值会返回-240,即-4:00.您需要使用分钟而不是小时,因为某些国家/地区的时区偏移为半小时或四分之一小时.
最后,当心. TIMESTAMP数据类型不代表1970年之前的时间.而且,在我的MariaDB 10.0实例上,当时间从32位开始递减时,它似乎在2038-01-19T03:14:07 UTC之后立即陷入死机.