3

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

我通过使用登录用户的时区(在本例中为 BST)在 PHP 中创建时间戳来插入任务。例如,我有一个任务设置为在 1351396800 运行,这是明天早上 4 点格林威治标准时间。

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

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

当明天凌晨 2 点时钟回退一小时时,这个设置可以吗?

更新:PHP 可以很好地转换日期。将 PHP 时区设置为 Europe/Dublin(当前为 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        |
4

2 回答 2

1

tl; dr 只要您的exec_time列具有 TIMESTAMP 数据类型,您就应该没问题。

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

因此,如果您将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

于 2012-10-27T21:03:41.047 回答
0

In answer to your question, it depends how critical the time fields are, and whether the server's local time will change or not. If it's UTC then it probably won't change.

The temporal types in MySQL aren't timezone aware. You'll have to implement timezones yourself, perhaps by always storing a UTC timestamp/datetime and a separate timezone column which contains an interval offset from +12 to -12 hours for how much time to add or subtract to the UTC timestamp for the timezone.

The actual handling of what value to put in the timezone field and the work needed to retrieve a timestamp adjusted for the timezone are up to you, unfortunately.

If switching to Postgres is an option then you can always use the TIMESTAMP WITH TIMEZONE type that Postgres supplies.

于 2012-10-27T20:28:19.337 回答