
只要您为当前时区设置了正确的时间,知道您存储的datetime列的时区,并且知道夏时制的问题,服务器上的时区似乎就没有关系。
另一方面,如果您可以控制所使用服务器的时区,则可以在内部将所有内容设置为UTC,而不必担心时区和DST。
以下是我收集的一些注意事项,这些注意事项涉及如何使用时区作为自己和他人的备忘单的形式,这可能会影响该人将为其服务器选择哪个时区以及他/她将如何存储日期和时间。
MySQL时区备忘单笔记:
- 更改时区 不会更改存储的日期时间或时间戳 ,但会从时间戳列中选择其他日期时间
- 警告! UTC具有leap秒,这看起来像是“ 2012-06-30 23:59:60”,由于地球自转速度变慢,可以在提前6个月通知的情况下随机添加
GMT混淆了秒,这就是发明UTC的原因。
警告! 由于夏令时,不同的区域时区可能会产生相同的日期时间值
由于受限制,因此timestamp列仅支持1970-01-01 00:00:01到2038-01-19 03:14:07 UTC日期。
- 在内部,MySQL时间戳列存储为UTC,但选择日期时,MySQL会自动将其转换为当前会话时区。
在时间戳中存储日期时,MySQL将假定该日期在当前会话时区中,并将其转换为UTC进行存储。
- MySQL可以在datetime列中存储部分日期,这些日期看起来像是“ 2013-00-00 04:00:00”
- 如果将datetime列设置为NULL,则MySQL将存储“ 0000-00-00 00:00:00”,除非您在创建该列时专门将其设置为允许null。
- 读这个
无论当前MySQL会话位于哪个时区:
SELECt CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` FROM `table_name`
您还可以将服务器或全局或当前会话时区设置为UTC,然后选择时间戳,如下所示:
要选择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。
要获取当前的UNIX时间戳(以秒为单位):将timestamp列获取为UNIX时间戳SELECT UNIX_TIMESTAMP(NOW());SELECT UNIX_TIMESTAMP();
获取UTC日期时间列作为UNIX时间戳记SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
从正UNIX时间戳整数获取当前时区datetimeSELECt UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
从UNIX时间戳获取UTC日期时间SELECt FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
从负UNIX时间戳整数获取当前时区datetimeSELECt 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中可以在3个地方设置时区:注意:时区可以两种格式设置:
- 与UTC的偏移量:“ + 00:00”,“ + 10:00”或“ -6:00”
- 作为指定的时区:“欧洲/赫尔辛基”,“美国/东部”或“ MET”
在文件“ my.cnf”中仅当已创建并填充mysql数据库中的时区信息表时,才能使用命名时区。
default_time_zone='+00:00'
要么
@@ global.time_zone变量timezone='UTC'
查看它们设置为什么值
SELECT @@global.time_zone;
要为其设置值,请使用以下任一方法:
@@ session.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:
设置mysql时区表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.sqlecho "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sqlcat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sqlmysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(确保您的服务器dst规则是最新的
zdump -v Europe/Moscow | grep 2011
https://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_dateFROM mysql.`time_zone_transition` tztINNER 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 changesORDER BY tzt.Transition_time ASCCONVERT_TZ还会根据上表中的规则和使用日期应用所有必要的DST更改。
注意:
根据docs,您为time_zone设置的值不会更改,例如,如果将其设置为“
+01:00”,则time_zone将设置为UTC的偏移量,它不遵循DST,因此它将全年保持不变。
在夏令时期间,只有指定的时区会更改时间。
像这样的缩写
CET将始终是冬季时间,
CEST将是夏季时间,而+01:00则始终是
UTC时间+ 1小时,并且两者都不会随着DST更改。
的
system时区将被安装的MySQL,其中主机的时区(除非MySQL的失败来确定它)
您可以在此处阅读有关使用DST的更多信息
相关问题:
- 如何设置MySQL的时区?
- MySql-UTC格式的SELECt时间戳列
- 如何从UTC时间获取MySQL中的Unix时间戳?
- 将服务器MySQL时间戳转换为UTC
- https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- 如何获取MySQL的当前时区?
- MySQL日期时间字段和夏时制-我如何引用“额外”小时?
- 从FROM_UNIXTIME转换负值
资料来源:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/refman/5.1/zh-CN/datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/rant/MySQL-timezones.txt
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)