mysql - 如何在脚本中处理MySQL时区

标签 mysql datetime timezone unix-timestamp datetime-conversion

我正在开发一个移动应用程序。从应用程序调用一个web服务,该服务根据模式运行不同的查询?模式=xx)
在某些查询中,我使用日期函数,如date(NOW())。
存储在MySQL数据库中的数据存储在GMT-7(加拿大山地时间)中。
我还没有为这个web服务注册一个域/主机,但是当我注册的时候,我们可以说它是在另一个城市托管的,比如多伦多(这是GMT-5-2小时之前)。然后在加拿大山地时间晚上10:05,用户使用该应用程序发送一个web请求呼叫,该呼叫具有如下查询:

SELECT DATE(NOW()) 

因为服务器托管在多伦多,所以它将返回明天的日期,即使用户所在的位置是前一天,并且应用程序显示基于当前日期的数据。
有人对此有什么想法吗?
编辑:
SYSTEM
2015-01-29 16:19:48
2015-01-29 23:19:48

是运行查询select@@时区,now(),utc\u timestamp()的结果
查询处理日期(yyyy-mm-dd)和时间(hh:mm:ss)列类型。

最佳答案

您在MySQL服务器上运行了这次诊断查询。

select @@time_zone, now(), utc_timestamp()

从本地时间和utc时间可以清楚地看到,服务器计算机的系统时区设置为“Canada/Mountain”,而MySQL服务器软件没有自己的时区设置。
如果您拿起您的表并将其原封不动地移动到附近时区的服务器上,则可以始终更新您的软件以发出命令
set time_zone = 'Canada/Mountain';

从软件连接后。这将使您的新MySQL连接的行为与当前连接的时区行为类似。如果您拥有MySQL服务器,可以根据本页的说明设置其默认时区。http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
下面是关于时间数据类型的故事。DATETIMEDATETIME都不知道时区。一旦您存储了日期/时间值,即使您更改了时区设置,您也会得到相同的值。
TIMESTAMP数据类型对时区敏感。这些数据项总是存储在UTC, also known as Z, time中,以前称为格林威治标准时间。它们在存储时始终转换为UTC,在检索时始终转换回UTC。
获取当前日期和时间(NOW()和朋友)的builtin functions对时区敏感。它们将在当地时间产生价值。例外情况是以UTC_开头的三个函数在UTC时间内产生值。
许多MySQL多时区应用程序使用以下操作规程:
向每个用户询问一个用户首选时区,或者从有关该用户的其他一些个人数据中找出它。(电话已从网络向其提供此信息)代表用户将其存储为zoneinfo-friendly时区描述符(“美洲/纽约”、“加拿大/山区”、“欧洲/维也纳”等)。
在代表用户建立一个MySQL会话时,使用一个set time_zone查询设置用户的时区,如上图所示。你应该在手术后马上做。
将用户的日期和时间存储到connect数据类型中。它们将在存储时转换为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实例中,它似乎在2038-01-19T03:14:07 UTC之后的一个桶中下地狱,时间从32位滚出来。

关于mysql - 如何在脚本中处理MySQL时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28226367/

相关文章:

mysql - 连接到 mysql 服务器 : ERROR 2003 (HY000) 时出现问题

mysql - LEFT JOIN 表 B 与表 C 的行数

mysql - 克隆表,包括多个 pk

php - UTF-8贯穿始终

php - 将 jquery datepicker 创建的日期转换为标准的 mysql dateformat

python - 如何访问 datetime Python 中的值?

python - 什么是 django 日期时间字段格式

java - Calendar.getTime() 不显示给定时区的日期时间

postgresql - PostgreSQL 中的时区转换不一致

java - 多个java的TimeZone被定向到单个joda的DateTimeZone