热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

MySQL是否应该将

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

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

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

MySQL 时区备忘单

笔记:


  1. 更改时区 ,但会从时间戳列中选择不同的日期时间


  2. UTC 有闰秒,这些看起来像 ‘2012-06-30 23:59:60’ 并且可以随机添加,由于地球自转速度减慢,提前 6 个月通知


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


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


  5. 由于限制,时间戳列仅支持日期 1970-01-01 00:00:01 到 2038-01-19 03:14:07 UTC 。


  6. MySQL 时间戳列在内部存储为UTC,但在选择日期时,MySQL 会自动将其转换为当前会话时区。


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


  1. MySQL 可以在日期时间列中存储部分日期,这些看起来像“2013-00-00 04:00:00”


  2. 如果您将日期时间列设置为 NULL,MySQL 将存储“0000-00-00 00:00:00”,除非您在创建该列时专门设置该列以允许为空。



选择 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`

要选择 UTC 中的当前日期时间:

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。

获取当前 UNIX 时间戳(以秒为单位):

SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();

获取时间戳列作为 UNIX 时间戳

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

获取 UTC 日期时间列作为 UNIX 时间戳

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

从正 UNIX 时间戳整数获取当前时区日期时间

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

从 UNIX 时间戳获取 UTC 日期时间

SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`

从负 UNIX 时间戳整数中获取当前时区日期时间

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)

在 MySQL 中有 3 个地方可以设置时区:

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


  1. 与 UTC 的偏移量:“+00:00”、“+10:00”或“-6:00”

  2. 作为命名时区:“欧洲/赫尔辛基”、“美国/东部”或“MET”


只有在 mysql 数据库中的时区信息表已创建并填充后,才能使用命名时区。


在文件“my.cnf”中

default_time_zOne='+00:00'

或者

timezOne='UTC'

@@global.time_zone 变量

查看它们设置为什么值

SELECT @@global.time_zone;

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

SET GLOBAL time_zOne= '+8:00';
SET GLOBAL time_zOne= 'Europe/Helsinki';
SET @@global.time_zOne='+00:00';

@@session.time_zone 变量

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`

设置mysql时区表

为了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

如果此命令给出错误“ data too long for column ‘abbreviation’ at row
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

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

查看每个时区的完整 DST(夏令时)转换历史

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 的偏移量,它不遵循
DST,所以它将全年保持不变。

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

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

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

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

传奇人物 Jon Skeet 何时不使用
UTC:https ://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-
silver-bullet/ (例如未来的预定活动代表一个时间,而不是一个瞬间)





推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了PHP常量的定义和使用方法,包括常量的命名规则、大小写敏感性、全局范围和标量数据的限制。同时还提到了应尽量避免定义resource常量,并给出了使用define()函数定义常量的示例。 ... [详细]
author-avatar
80后之多管闲事
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有