当手动设置time_zone时,UNIX_TIMESTAMP在MySQL中给出意外值

时间:2015-08-26 08:37:18

标签: mysql date timezone

我目前正在研究在不同时区运行的客户端和服务器的MySQL日期和时间的行为。我正在编写测试脚本,以便测试当我在某些时区使用客户端和服务器运行时发生了什么,并且作为该工作的一部分,我需要能够控制会话时区。我在将时区设置为我的系统当前默认的同一时区时遇到问题,因此它的行为完全相同。

我想设置mysql SESSION time_zone变量集,以便以与将time_zone变量保留为默认SYSTEM值时相同的方式解释日期。当我手动将time_zone设置为Europe / London时,我希望UNIX_TIMESTAMP继续以与time_zone设置为SYSTEM时相同的方式运行,因为我的mysql system_time_zone设置为在伦敦(GMT夏令时或GMT标准)时间)。相反,我发现UNIX_TIMESTAMP函数返回不同的值,具体取决于time_zone是否设置为' SYSTEM'或者'欧洲/伦敦',如您所见: -

在英国夏令时将日期设置为8月25日,并重新启动MySQL服务器,以便使用system_time_zone =' GMT Summer Time'你可以看到当time_zone是SYSTEM(即GMT夏令时)并且设置为Europe / London时,UNIX_TIMESTAMP函数返回不同的值: -

$ date; mysql --protocol=TCP -uroot -proot mysql  -e "show variables LIKE 'system_time_zone'; SET SESSION time_zone = 'SYSTEM'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1970-01-01 12:00:00');SET SESSION time_zone = 'Europe/London'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1970-01-01 12:00:00');";
25 Aug 2015 09:12:20
+------------------+-----------------+
| Variable_name    | Value           |
+------------------+-----------------+
| system_time_zone | GMT Summer Time |
+------------------+-----------------+
+---------------------+
| @@SESSION.time_zone |
+---------------------+
| SYSTEM              |
+---------------------+
+---------------------+
| NOW()               |
+---------------------+
| 2015-08-25 09:12:21 |
+---------------------+
+---------------------------------------+
| UNIX_TIMESTAMP('1970-01-01 12:00:00') |
+---------------------------------------+
|                                 43200 |
+---------------------------------------+
+---------------------+
| @@SESSION.time_zone |
+---------------------+
| Europe/London       |
+---------------------+
+---------------------+
| NOW()               |
+---------------------+
| 2015-08-25 09:12:21 |
+---------------------+
+---------------------------------------+
| UNIX_TIMESTAMP('1970-01-01 12:00:00') |
+---------------------------------------+
|                                 39600 |
+---------------------------------------+
MyPc
$

将英国冬季时间设置为12月24日,并重新启动mysql服务器,以便使用system_time_zone =' GMT标准时间'我仍然得到相同的结果,因此system_time_zone是在夏天还是标准时间似乎没有什么区别: -

$ date; mysql --protocol=TCP -uroot -proot mysql  -e "show variables LIKE 'system_time_zone'; SET SESSION time_zone = 'SYSTEM'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1970-01-01 12:00:00');SET SESSION time_zone = 'Europe/London'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1970-01-01 12:00:00');";
25 Dec 2015 09:14:13
+------------------+-------------------+
| Variable_name    | Value             |
+------------------+-------------------+
| system_time_zone | GMT Standard Time |
+------------------+-------------------+
+---------------------+
| @@SESSION.time_zone |
+---------------------+
| SYSTEM              |
+---------------------+
+---------------------+
| NOW()               |
+---------------------+
| 2015-12-25 09:14:14 |
+---------------------+
+---------------------------------------+
| UNIX_TIMESTAMP('1970-01-01 12:00:00') |
+---------------------------------------+
|                                 43200 |
+---------------------------------------+
+---------------------+
| @@SESSION.time_zone |
+---------------------+
| Europe/London       |
+---------------------+
+---------------------+
| NOW()               |
+---------------------+
| 2015-12-25 09:14:14 |
+---------------------+
+---------------------------------------+
| UNIX_TIMESTAMP('1970-01-01 12:00:00') |
+---------------------------------------+
|                                 39600 |
+---------------------------------------+
MyPc
$

我可以从cygwin TZ变量中看到我的Windows时区设置为欧洲/伦敦: -

MyPc
$ echo $TZ
Europe/London
MyPc
$

我的问题是: -

  1. 为什么UNIX_TIMESTAMPs在看起来时区应该被视为相同时返回不同?
  2. 如何设置我的时区以便UNIX_TIMESTAMP(和其他所有内容)的行为与time_zone设置为默认SYSTEM值时的行为相同?
  3. 更新

    我想我可能已回答了我自己的问题。我在1971年10月31日之前发现GMT和UTC NOT 相同,你可以看到: -

    http://www.timeanddate.com/time/change/uk/london?year=1970

    http://www.timeanddate.com/time/change/uk/london?year=1971

    (尝试上述1972年和1973年的链接)

    这是因为BST在1971年夏天并不存在,所以在那个夏天GMT比UTC早一个小时,然后在1971年10月31日,时钟第一次回归,GMT与之同步UTC。

    因此,如果我像上面那样进行相同的测试,但是使用1973作为年份,那么我获得了与Unix时间戳相同的值(如预期的那样)。这必须意味着当我离开时区时,系统MySQL将日期解释为UTC日期,因此给出12 * 3600 = 43200但是当我将time_zone设置为欧洲/伦敦时,它认为时间意味着英国GMT在冬天1970年是UTC的一小时,因此1970年1月1日中午是11:00 UTC = 11 * 3600 = 39600,如下所示: -

    $ date; mysql --protocol=TCP -uroot -proot mysql  -e "show variables LIKE 'system_time_zone'; SET SESSION time_zone = 'SYSTEM'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1973-01-01 12:00:00');SET SESSION time_zone = 'Europe/London'; SELECT @@SESSION.time_zone; select NOW(); select UNIX_TIMESTAMP('1973-01-01 12:00:00');";
    25 Aug 2015 12:33:36
    +------------------+-----------------+
    | Variable_name    | Value           |
    +------------------+-----------------+
    | system_time_zone | GMT Summer Time |
    +------------------+-----------------+
    +---------------------+
    | @@SESSION.time_zone |
    +---------------------+
    | SYSTEM              |
    +---------------------+
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2015-08-25 12:33:37 |
    +---------------------+
    +---------------------------------------+
    | UNIX_TIMESTAMP('1973-01-01 12:00:00') |
    +---------------------------------------+
    |                              94737600 |
    +---------------------------------------+
    +---------------------+
    | @@SESSION.time_zone |
    +---------------------+
    | Europe/London       |
    +---------------------+
    +---------------------+
    | NOW()               |
    +---------------------+
    | 2015-08-25 12:33:37 |
    +---------------------+
    +---------------------------------------+
    | UNIX_TIMESTAMP('1973-01-01 12:00:00') |
    +---------------------------------------+
    |                              94737600 |
    +---------------------------------------+
    MyPc
    $
    

    为了避免这个问题,我将从现在开始使用 1973之后的日期进行所有必须测试,并且只是怜悯那些必须在MySQL中处理1973年之前的日期的人。如果这是一个MySQL错误,我不会感到惊讶,因为看起来GMT的系统时区应该完全映射到欧洲/伦敦的SESSION时区,但不是。

0 个答案:

没有答案