MySql UNIX_TIMESTAMP()以UTC的形式存储,夏令时即将来临

时间:2012-10-27 20:10:55

标签: php mysql utc unix-timestamp dst

我的数据库服务器(运行MySql 5.5)设置为UTC,使用UNSIGNED INT将日期作为Unix时间戳存储在数据库中。该数据库主要用于存储在特定时间(exec_time)运行的任务。

我通过使用登录用户的时区(在本例中为BST)在PHP中创建时间戳来插入任务。例如,我的任务设置为1351396800,即明天早上4点GMT。

我使用以下查询从数据库中提取任务:

SELECT * FROM tasks WHERE exec_time <= UNIX_TIMESTAMP();

当时钟明天凌晨2点回滚时,这个设置会好吗?

更新:PHP正在将日期转换为正常。将PHP时区设置为欧洲/都柏林(目前为BST)将在午夜12点和凌晨4点添加的两个事件存储如下:

mysql> select exec_time, FROM_UNIXTIME(exec_time) from tasks order by id desc limit 2;
+-------------+----------------------------+
| exec_time | FROM_UNIXTIME(exec_time) |
+-------------+----------------------------+
|  1351378800 | 2012-10-27 23:00:00        |
|  1351396800 | 2012-10-28 04:00:00        |

2 个答案:

答案 0 :(得分:1)

tl; dr只要您的exec_time列具有TIMESTAMP数据类型,您就可以了。

没有明确的UNIX_TIMESTAMP列数据类型。有一个TIMESTAMP列数据类型。当从日期/时间字符串和UTC转换时,此数据类型的列的值将自动从客户端连接的时区转换为UTC(a / k / a Z或Zulu时间,f / k /格林威治标准时间)转换为日期/时间字符串后,转到客户端连接的时区。

因此,如果您将exec_time列存储为TIMESTAMP,则应该能够使用您建议的条款:

  WHERE exec_time <= UNIX_TIMESTAMP()

这将有效,因为您的exec_time值和UNIX_TIMESTAMP()函数调用的结果都在服务器端以UTC格式处理。您的exec_time值将以UTC格式存储。

如果您将exec_time存储为UNSIGNED INT或类似的数字数据类型,则在存储之前,您将无法利用自动转换为UTC。

您可以通过设置客户端连接time_zone来解决显示转换行为,如下所示:

  SET time_zone='SYSTEM'   /* for your system's local time */

  SET time_zone='+0:00'   /* for UTC */

  SET time_zone'America/New_York' /* or 'Europe/Vienna' or whatever */

一旦您发布了其中一个SET操作,请执行

 SELECT exec_time, FROM_UNIXTIME(exec_time) 

了解您的值如何存储在服务器端并进行翻译。

如果你想看看八天会发生什么,试试这个:

 SELECT 3600*24*8+exec_time, FROM_UNIXTIME(3600*24*8+exec_time) 

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

答案 1 :(得分:0)

在回答您的问题时,这取决于时间字段的重要程度,以及服务器的本地时间是否会发生变化。如果它是UTC那么它可能不会改变。

MySQL中的时间类型不是时区感知的。您必须自己实现时区,可能始终存储UTC时间戳/日期时间和单独的时区列,其中包含从+12到-12小时的间隔偏移量,以便为时区添加或减去UTC时间戳的时间长度。

遗憾的是,实际处理时区字段中的值以及检索为时区调整的时间戳所需的工作取决于您。

如果选择切换到Postgres,则可以始终使用Postgres提供的TIMESTAMP WITH TIMEZONE类型。