您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

MySQL是否应将其时区设置为UTC?

MySQL是否应将其时区设置为UTC?

只要您为当前时区设置了正确的时间,知道您存储的datetime列的时区,并且知道夏时制的问题,服务器上的时区似乎就没有关系。

另一方面,如果您可以控制所使用服务器的时区,则可以在内部将所有内容设置为UTC,而不必担心时区和DST。

以下是我收集的一些注意事项,这些注意事项涉及如何使用时区作为自己和他人的备忘单的形式,这可能会影响该人将为其服务器选择哪个时区以及他/她将如何存储日期和时间。

笔记:

GMT混淆了秒,这就是发明UTC的原因。

由于夏令时,不同的区域时区可能会产生相同的日期时间值

由于受限制,因此timestamp列仅支持1970-01-01 00:00:01到2038-01-19 03:14:07 UTC日期。

在时间戳中存储日期时,MysqL将假定该日期在当前会话时区中,并将其转换为UTC进行存储。

无论当前MysqL会话位于哪个时区:

SELECT 
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` 
FROM `table_name`

您还可以将服务器或全局或当前会话时区设置为UTC,然后选择时间戳,如下所示:

SELECT `timestamp_field` FROM `table_name`
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(Now(), @@session.time_zone, '+00:00');

结果示例: 2015-03-24 17:02:41

SELECT Now();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
SELECT @@system_time_zone;

例如,在莫斯科时间返回“ MSK”或“ +04:00”,这是一个(或曾经是)一个MysqL错误,如果将其设置为数值偏移量,则不会调整夏令时

SELECT TIMEDIFF(Now(), UTC_TIMESTAMP);

如果您的时区为+2:00,它将返回02:00:00。

SELECT UNIX_TIMESTAMP(Now());
SELECT UNIX_TIMESTAMP();
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00') 
FROM `table_name`
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)

注意:时区可以两种格式设置:

仅当已创建并填充MysqL数据库中的时区信息表时,才能使用命名时区。

default_time_zone='+00:00'

要么

timezone='UTC'

查看它们设置为什么值

SELECT @@global.time_zone;

要为其设置值,请使用以下任一方法

SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
SELECT @@session.time_zone;

要设置它,请使用以下任一方法

SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";

“ @@ global.time_zone变量”和“ @@ session.time_zone变量”都可能返回“ SYstem”,这意味着它们使用在“ my.cnf”中设置的时区。

http//dev.mysql.com/doc/refman/5.1/en/time-zone-support。 html

注意:您不能执行此操作,因为它将返回NULL:

SELECT 
CONVERT_TZ(`timestamp_field`, TIMEDIFF(Now(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime` 
FROM `table_name`

为了CONVERT_TZ工作,您需要填充时区表

SELECT * FROM MysqL.`time_zone` ;
SELECT * FROM MysqL.`time_zone_leap_second` ;
SELECT * FROM MysqL.`time_zone_name` ;
SELECT * FROM MysqL.`time_zone_transition` ;
SELECT * FROM MysqL.`time_zone_transition_type` ;

如果它们为空,则通过运行此命令将其填满

MysqL_tzinfo_to_sql /usr/share/zoneinfo | MysqL -u root -p MysqL

如果此命令给您错误数据在行1的列’缩写’时过长 ”,则可能是由于在时区缩写的末尾附加了NULL字符引起的

解决此问题的方法

MysqL_tzinfo_to_sql /usr/share/zoneinfo | MysqL -u root -p MysqL
(if the above gives error "data too long for column 'abbreviation' at row 1")
MysqL_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql

echo "SET SESSION sql_mode = '';" > /tmp/MysqL_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/MysqL_tzinfo_to.sql

MysqL --defaults-file=/etc/MysqL/my.cnf --user=verifiedscratch -p MysqL < /tmp/MysqL_tzinfo_to.sql

(确保您的服务器dst规则是最新的zdump -v Europe/Moscow | grep 2011https://chrisjean.com/updating-daylight-saving-time-on- linux/)

SELECT 
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND)  AS transition_date
FROM MysqL.`time_zone_transition` tzt
INNER JOIN MysqL.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN MysqL.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC

CONVERT_TZ 还会根据上表中的规则和使用日期应用所有必要的DST更改。

根据docs,您为time_zone设置的值不会更改,例如,如果将其设置为“ +01:00”,则time_zone将设置为UTC的偏移量,它不遵循DST,因此它将全年保持不变。

在夏令时期间,只有指定的时区会更改时间。

像这样的缩写CET将始终是冬季时间,CEST将是夏季时间,而+01:00则始终是UTC时间+ 1小时,并且两者都不会随着DST更改。

system时区将被安装的MysqL,其中主机的时区(除非MysqL的失败来确定它)

您可以在此处阅读有关使用DST的更多信息

相关问题:

资料来源:

MySQL 2022/1/1 18:18:33 有510人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶