我正在开发一个移动应用程序。从应用程序调用到基于模式(?mode = xx)运行不同查询的Web服务。
在其中一些查询中,我使用DATE(NOW())之类的日期函数。
MySQL数据库中存储的数据存储在GMT-7(加拿大山地时间)中。
我尚未为该Web服务注册域/主机,但是当我这样做时,可以说它托管在另一个城市中,例如多伦多(格林尼治标准时间5-2小时)。然后在加拿大山区时间晚上10:05,用户使用该应用程序发送网络查询呼叫,该查询具有以下查询:
SELECT DATE(NOW())
因为服务器托管在多伦多,所以即使用户位于前一天,该应用程序也会根据明天显示日期,而返回明天的日期。
有人对此有任何想法吗?
编辑:
SYSTEM
2015-01-29 16:19:48
2015-01-29 23:19:48
是运行查询的结果select @@ time_zone,now(),utc_timestamp()
查询处理日期(yyyy-mm-dd)和时间(hh:mm:ss)列类型。
您在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中,也称为Z时间,以前称为格林威治标准时间。它们在存储时总是转换为UTC,而在检索时总是转换回。
用于获取当前日期和时间(以及朋友)的内置函数对时区敏感。他们将在当地时间产生值。唯一的例外是三个函数,它们以UTC时间产生值。NOW()
UTC_
许多MySQL多时区应用程序都遵循以下操作准则:
set time_zone
上面显示的查询设置用户的时区。您应该在connect
手术后立即执行此操作。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之后就陷入了混乱。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句