问题描述
我知道警告是由 DST 发出的,但为什么 QUERY 的结果不同:
SELECT CONVERT_TZ('2002-10-23T15:57:03Z','SYstem','America/Bogota')
当我在 CentOs 7 中运行 QUERY 时:
[VERSION()] => 5.7.33
[@@SESSION.sql_mode] => ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
[@@session.time_zone] => GMT
从 MysqL 我得到
NULL
当我在 Windows 10 中运行查询时:
[VERSION()] => 5.7.33
[@@SESSION.sql_mode] => ONLY_FULL_GROUP_BY,NO_ENGINE_SUBSTITUTION
[@@session.time_zone] => GMT
从 MysqL 我得到
[CONVERT_TZ('2002-10-23T15:57:03Z','GMT','America/Bogota')] => 2002-10-23 10:57:03
WARNING (
[Level] => Warning
[Code] => 1292
[Message] => Truncated incorrect datetime value: '2002-10-23T15:57:03Z'
)
如果两个服务器都有相同的环境,为什么结果不同?
在 Windows 中我没有 my.ini
这是 CentOs 7 中的文件 my.ini
:
# For advice on how to change settings please see
# http://dev.MysqL.com/doc/refman/5.7/en/server-configuration-defaults.html
[MysqLd]
performance-schema=0
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MysqL. Start at 70% of total RAM for dedicated server,else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed,experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/MysqL
socket=/var/lib/MysqL/MysqL.sock
# disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log-error=/var/log/MysqLd.log
pid-file=/var/run/MysqLd/MysqLd.pid
innodb_buffer_pool_size=53477376
max_allowed_packet=268435456
open_files_limit=40000
innodb_file_per_table=1
default_storage_engine=MyIsam
default_tmp_storage_engine=MyIsam
character_set_server=utf8mb4
collation_server=utf8mb4_general_ci
解决方法
MySQL 在时区方面有点蹩脚。
无法识别尾随的 Z
,但我认为您只会收到警告。
你有加载时区表吗? (我不知道这是否是您安装中的一个单独步骤。请参阅 https://dev.mysql.com/downloads/timezones.html )
这样效果更好,但需要知道调整因子:
mysql> SELECT CONVERT_TZ('2002-10-23T15:57:03','SYSTEM','-05:00');
+-------------------------------------------------------+
| CONVERT_TZ('2002-10-23T15:57:03','-05:00') |
+-------------------------------------------------------+
| 2002-10-23 17:57:03 |
+-------------------------------------------------------+
时间戳
TIMESTAMP
只不过是一个数字——从 1970 年开始的秒数。但是,在存储/获取时,基于某些设置的时区信息会从系统时间转换为/从 UTC:
mysql> SHOW VARIABLES LIKE '%zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | PDT |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.01 sec)
SYSTEM
基于操作系统设置。
日期时间
DATETIME
(以及仅限日期的 DATE
)本质上是您墙上的时钟图片。也就是说,除了您在此处可以看到的内容之外,没有存储在其中的信息:
mysql> SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2021-04-19 09:35:23 |
+---------------------+
1 row in set (0.00 sec)
不存储时区信息。字符串中也不包含任何 TZ 信息:
mysql> SELECT HOUR('2021-04-19 09:35:23 -07:00');
+------------------------------------+
| HOUR('2021-04-19 09:35:23 -07:00') |
+------------------------------------+
| 9 |
+------------------------------------+
1 row in set,1 warning (0.00 sec)
mysql> show warnings;
+---------+------+--------------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '2021-04-19 09:35:23 -07:00' |
+---------+------+--------------------------------------------------------------+
1 row in set (0.00 sec)
亚秒 毫秒示例。 (最多可以使用 6 个)
mysql> SELECT NOW(3),CURRENT_TIMESTAMP(3);
+-------------------------+-------------------------+
| NOW(3) | CURRENT_TIMESTAMP(3) |
+-------------------------+-------------------------+
| 2021-04-19 09:49:55.292 | 2021-04-19 09:49:55.292 |
+-------------------------+-------------------------+
1 row in set (0.00 sec)
参考
从 MySQL 8.0.19 开始,您可以在将 TIMESTAMP 和 DATETIME 值插入表中时指定时区偏移量。偏移量附加到日期时间文字的时间部分,没有插入空格,并使用与设置 time_zone 系统变量相同的格式,但有以下例外:
对于小于 10 的小时值,需要前导零。
值“-00:00”被拒绝。
不能使用'EET'和'Asia/Shanghai'等时区名称; 在此上下文中也不能使用“SYSTEM”。
插入的值不能为月部分,即日 部分,或两部分。这是从 MySQL 8.0.22 开始强制执行的, 无论服务器 SQL 模式设置如何。
来自 https://dev.mysql.com/doc/refman/8.0/en/datetime.html ,它可能有更多感兴趣的信息。
这也表明 8.0.22 具有:
CAST(col AT TIME ZONE INTERVAL '+00:00' AS DATETIME)
这可能对你有帮助。