当前位置: 首页 > 知识库问答 >
问题:

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

欧阳正德
2023-03-14

利弊何在?

共有1个答案

松建本
2023-03-14

服务器上的时区似乎并不重要,只要您为当前时区设置了正确的时间,知道存储的datetime列的时区,并且了解夏令时的问题。

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

以下是我收集的一些笔记,说明如何使用时区作为自己和其他人的备查表,这些备查表可能会影响用户将为其服务器选择什么时区,以及他/她将如何存储日期和时间。

备注:

>

  • 更改时区不会更改存储的日期时间或时间戳,但会从时间戳列中选择不同的日期时间
  • 警告!UTC有闰秒,这些闰秒看起来像“2012-06-30 23:59:60”,可以随机添加,提前6个月通知,因为地球自转减慢
  • GMT混淆秒数,这就是UTC被发明的原因。

    警告!由于夏令时,不同的区域时区可能产生相同的datetime值

    SELECT 
    CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` 
    FROM `table_name`
    
    SELECT `timestamp_field` FROM `table_name`
    
    SELECT UTC_TIMESTAMP();
    SELECT UTC_TIMESTAMP;
    SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
    
    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) 
    

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

      null
    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”中设置的时区。

    SELECT 
    CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime` 
    FROM `table_name`
    
    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行的列'abbreviation'数据太长”,则可能是由于在时区缩写的末尾追加了空字符所导致的。“data too long for column'abbreviation'”(data too long for column'abbreviation“)

    修复程序是运行这个

    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更改。

    注意:
    根据文档,您为time_zone设置的值不变,例如设置为“+01:00”,则time_zone将设置为与UTC的偏移量,而UTC不遵循DST,因此全年不变。

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

    系统时区将是安装mysql的主机的时区(除非mysql无法确定)

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

    相关问题:

      null
      null

  •  类似资料:
    • 问题内容: https://serverfault.com/questions/191331/should-servers-have-their-timezone- set-to-gmt-utc的 后续问题 是将MySQL时区设置为UTC还是将其设置为与服务器或PHP相同的时区?(如果不是UTC) 优缺点都有什么? 问题答案: 只要您为当前时区设置了正确的时间,知道您存储的datetime列的时区

    • 在我的airflow升级到2.0.0(然后是2.0.1)并且调度程序扩展到3个节点之后,奇怪的事情发生了: DAGRUNN成功,但根本没有计划任务实例 任务失败,主机名为空(https://github.com/apache/airflow/issues/13692) 任务设置为“upstream_failed”,而上游任务成功(https://github.com/apache/airflow/

    • 问题内容: 我需要更改单个数据库的时区吗? 我知道我们可以在WHM中更改时区(我们正在使用hostgator的专用服务器),但是服务器上运行的大量旧版软件中有很多+6小时的编码(即服务器时区为CST,需要GMT时间,因此以前的开发人员会在代码中手动更改日期/时间- 很糟糕!)。 我现在正在开发一个新软件,并希望将其全部保存在GMT中,我知道我可以使用date_default_timezone_se

    • 问题内容: 我已经阅读了文档。但我仍然不确定何时不需要将其设置为。在下面的代码中,如果将其设置为,则根本看不到标题。如果我将其保留为,那么一切都很好。 View调试层次结构中的以下内容将给出警告“ 宽度 和 位置 不明确”。 我以为只要需要修改代码中的任何内容,都必须设置为。 如果您需要删除其所有约束,然后将其设置为,然后添加所需的内容,则可能是更正确的说法,在这种情况下,您需要为所有四个方面添加

    • 问题内容: 考虑以下(脆弱的)JavaScript代码: 问题 图像的宽度和高度是否应该立即正确? 画布绘制是否应该立即工作? 是否应该调用回调(在更改src之后设置)? 实验测试 我用类似的代码创建了一个简单的测试页面。在Safari我的第一次测试,都是由本地打开HTML网页(URL),并从我的服务器加载它,结果显示一切工作:高度和宽度是正确的,在画布上绘制的作品,并且在还火。 在Firefox

    • 我有一个mysql 5.7 docker容器。当我运行mysql命令时: 它显示了我当前时间的3小时(这是合乎逻辑的)。我想在配置文件中设置时区。遵循中的文档https://hub.docker.com/_/mysql/我在我的文件如下所示: 当我浏览容器中的文件时,文件。在该文件中,我尝试了一些解决方案,如: 或者是一种折衷方案,因为该区域每年必须更换两次(夏季/冬季),因此不太优雅: 但这一切