当前位置: 首页 > article >正文

mysql date/datetime/timestamp and timezone

获取Server时区

$ SELECT @@global.time_zone, @@session.time_zone, @@system_time_zone
@@global.time_zone: SYSTEM
@@session.time_zone: SYSTEM
@@system_time_zone: +08

获取和设置Connection时区

set time_zone="+00:00"
select now()

Datetime类型本质上是字符串存储的

由于Datetime是以字符串存储的,其值在写入时已经确定,只支持2020-02-02 20:20:20的写入。
所以,改变connection或者server的时区,不会更新已有的数据。

此外,如果对datetime作匹配,不会应用时区信息:

$ SELECT id,create_time FROM test_tab WHERE create_time="2023-03-13 11:51:00" \G'
*************************** 1. row ***************************
         id: 160482
create_time: 2023-03-13 11:51:00


$ SELECT id,create_time FROM test_tab WHERE create_time="2023-03-13 11:51:00+08:00" \G'
*************************** 1. row ***************************
         id: 160482
create_time: 2023-03-13 11:51:00

这说明Datetime和普通的字符串匹配不一样,mysql会把字符串先转成时区再进行操作

改变时区,并不会改变已有的数据。
我们可以将mysql对于Datetime类型的操作,可以理解为以下步骤:

  • 将时间标准化,移除多余的字符串

    • 2022-02-02 20:20:20XXXXX 多余的XXXX被移除掉,比如 2022-02-02 20:20:20z,看起来是0时区,但实际上最终和2022-02-02 20:20:20等价
    • 但是mysql8支持 +08:00的时区后缀: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-literals.html

    Beginning with MySQL 8.0.19, you can specify a time zone offset when inserting TIMESTAMP and DATETIME values into a table. The offset is appended to the time part of a datetime literal, with no intravening spaces, and uses the same format used for setting the time_zone system variable, with the following exceptions:

  • 再对时间进行存储或比较

Date相关的函数

https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_adddate

UNIX_TIMESTAMP(DATE)会受时区影响

$ SET time_zone="+00:00"
$ SELECT unix_timestamp("2023-03-13 11:51:00")\G
1678708260
$ SET time_zone="+08:00"
$ SELECT unix_timestamp("2023-03-13 11:51:00")\G
1678679460

1678679460s - 1678708260s = 28800s = 8h

对于不合法的日期,UNIX_TIMESTAMP返回0

$ select unix_timestamp("2")
0.000000
$ select unix_timestamp("2022")
0.000000
$ select unix_timestamp("2022-02-??")
0.000000
$ select unix_timestamp("2022-02-02")
1643731200

#  不合法的日期,比如12-32日,也返回0
$ select unix_timestamp("2022-12-32")
0

对于1970-01-01以前的日期,UNIX_TIMESTAMP返回0

$ SELECT unix_timestamp("1900-01-01")
0
$ SELECT unix_timestamp("1970-01-01")
0
$ SELECT unix_timestamp("1970-01-02")
59400

注意,nodejs中的getTime会返回负数的时间戳

> new Date("1970-01-01").getTime()
0
> new Date("1900-01-01").getTime()
-2208988800000

DATEDIFF对于1970-01-01以前的日期仍然有效

$ SELECT DATEDIFF("1901-01-01 23:59:59","1900-12-31 23:59:59")
1
$ SELECT DATEDIFF("1901-01-01 23:59:59","1900-12-32 23:59:59")
NULL

字面量(mysql5.7也支持)

SELECT TIME'20:20:20'
SELECT DATE'2020-02-02'
SELECT TIMESTAMP'2020-02-02 20:20:20'

有效的时间范围

DATE: 1000-01-01 to 9999-12-31
DATETIME: 1000-01-01 00:00:00 to 9999-12-31 23:59:59
TIMESTAMP: 1970-01-01 00:00:01 to 2038-01-19 03:14:07

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in ‘YYYY-MM-DD’ format. The supported range is ‘1000-01-01’ to ‘9999-12-31’.

The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in ‘YYYY-MM-DD hh:mm:ss’ format. The supported range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’.

TIMESTAMP has a range of ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC.

自动转换

https://dev.mysql.com/doc/refman/8.0/en/datetime.html
TIMESTAMP类型自动转换为UTC时间存储,查询时再转换为当前时区。
但是对于DATETIME类型没有这个转换,仅仅是以标准化后的字符串形式存储。

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.


http://www.kler.cn/news/9414.html

相关文章:

  • 模拟Redisson获取锁 释放锁 锁续命
  • 软件测试今天你被内卷了吗?
  • 【LeetCode每日一题: 516. 最长回文子序列 | 暴力递归=>记忆化搜索=>动态规划 | 区间dp 】
  • 【华为OD机试】1035 - 判断两个IP是否属于同一子网
  • OpenText Content Server 客户案例——全球最大的商业炸药和创新爆破系统供应商Orica
  • 数据结构exp1_2学生成绩排序
  • MySQL库的操作
  • 博瑞智能云音箱云喇叭API开发定时播报文档(2023-4-5)
  • Linux进程间通信
  • 计讯物联小型水库雨水情测报与大坝安全监测一体化解决方案,确保水库安全运行
  • SpringAMQP
  • 数字化转型的避坑指南:细说数字化转型十二大坑
  • 实验6 TensorFlow基础
  • 亚马逊测评只能下单上好评?卖家倾向养号测评还有这些骚操作
  • Drone+Gitea CICD环境搭建流程笔记
  • Git(四):远程仓库的搭建、获取与更新
  • redis基础总结-常用命令
  • 初识C语言 ——“C Primer Plus”
  • TOGAF—架构治理
  • leaflet使用L.geoJSON加载文件,参数onEachFeature的使用方法(129)
  • git常用命令
  • 【前端】VUE3去掉控制台的warn信息
  • redis set list
  • 一天吃透计算机网络八股文
  • 初识设计模式 - 命令模式
  • 【ROS2指南-12】编写一个简单的发布者和订阅者
  • IDEA2020.1 Failed to execute goal org.codehaus.mojo:exec-maven-plugin
  • Sentry安装使用(最全最细)
  • 你是真的“C”——宏与函数的英雄本色
  • fetch下载js文件,js内容浏览器能不执行吗