日期时间类型中包含以下几种数据类型:

各类型都有具体的取值范围,超出或非法的其他值时,MySQL 会回退到 0。TIMESTAMP 类型是个例外,给它设置一个超出范围的值时,将保存上该类型允许的最大值。

MySQL 按标准格式 YYYY-MM-DD hh:mm:ss[.fraction] 输出日期时间,但设置或进行日期时间相关的比较时却支持灵活的多种格式,会自动解析。具体支持的输入格式可参见 Section 9.1.3, “Date and Time Literals”。其中 fraction 部分为秒后面的小数部分,取值范围为 0~6 位。

虽然 MySQL 支持多种格式进行日期时间的设置,但日期部分要求必须是 年-月-日 的形式才能正确解析。比如 98-09-04 是按年月日顺序解析的,而不是英文里常用的月日年,或者日月年。

年在只给了两位数的情况下,MySQL 尝试使用以下规则来补全:

  • 给定的两位数为 70~99 时解析成 1970 ~ 1999。
  • 给定为 00 ~ 69 时解析成 2000 ~ 2069。

所以,为了避免不可预测的结果,使用时还是指定全一些。

  • 在需要使用数字的语境下,MySQL 会将日期时间自动转成数字。同理,在需要日期时间的相关操作语境下,会尝试将数字解析成日期时间。
  • 通过设置 MySQL 相关参数,日期类型可保存原本非法的值,比如开启 ALLOW_INVALID_DATES 设置项时,可设置日期类型保存一个 2009-11-31 值,但正常情况下我们知道 11 月哪来什么 31 号。此时 MySQL 仅仅只是不检查月分与日期的关联性,但月分的取值范围 112 及日期的取值范围 131 还是要单独各自做校验的。
mysql> INSERT INTO todo (title,created_on) VALUES ('blah','2019-09-31');
ERROR 1292 (22007): Incorrect date value: '2019-09-31' for column 'created_on' at row 1 mysql> SET SESSION sql_mode = 'ALLOW_INVALID_DATES';

Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO todo (title,created_on) VALUES ('blah','2019-09-31');

Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> SELECT * FROM todo;

+----+------+------------+

| id | title | created_on |

+----+------+------------+

| 1 | blah | 2019-09-31 |

+----+------+------------+

1 rows in set (0.00 sec)

某些场景下你可能需要保存部分日期,比如用户只输入了年没输入月日。所以 MySQL 是支持将月日设置成 0,比如 2019-00-00。但这种情况下就无法从日期相关的操作中获得到准确的结果,比如使用 DATE_SUB()DATE_ADD() 函数时。禁用月日的零值可通过开启 MySQL 的 NO_ZERO_IN_DATE 模式。

除了月日可零,MySQL 还支持设置年月日都零的值 0000-00-00,对于日期非必填的情况比较有用,因为此时它比单纯的 NULL 更有语义。可通过开启 MySQL 的 NO_ZERO_DATE 模式来禁用这个全零的值。

各日期时间零值格式如下,但实际时用时,直接简写成一个 0 效果是等效的。

Data Type “Zero” Value
DATE '0000-00-00'
TIME '00:00:00'
DATETIME '0000-00-00 00:00:00'
TIMESTAMP '0000-00-00 00:00:00'
YEAR 0000

DATE,DATETIME,及 TIMESTAMP

三者具有相关性,都支持多种格式的自动解析,详见 Date and Time Literals

DATE 日期格式不带时间 TIME 部分,查询时输出格式为 YYYY-MM-DD,取值范围为 1000-01-019999-12-31

DATETIME 包含日期及时间,输出格式为 YYYY-MM-DD hh:mm:ss,取值范围 1000-01-01 00:00:009999-12-31 23:59:59

TIMESTAMPDATETIME,但取值范围基于 UTC 时间,较 DATETIME 要小,为 1970-01-01 00:00:01 UTC 到 2038-01-19 03:14:07 UTC。所以使用 TIMESTAMP 格式的时间,到 2038 年会溢出,这就是 Year 2038 problem。关于该问题的讨论和解决可参见这个 StackOverflow 的回答

既然如此,为何要使用这个取值范围更小的呢。TIMESTAMP 存储的值是带时区的。在存储时会根据当前时区转成 UTC(universal time zone) 存储,查询时也会根据时区从 UTC 转换到具体的时间。对于支持多语及国际化全球部署的应用来说,显得尤为方便。需要注意的是,这里操作基于的时区默认为服务器的时区,可通过改变 time_zone SET GLOBAL time_zone=time_zone 来修改。时区的设置也可以是以连接为单位,这样来自不同时区的请求可得到不同的时间。

TIMESTAMPDATETIME 都可包含至多 6 位的小数来表示时间中毫秒(microseconds)的部分。所以,带上毫秒时完整的格式是 YYYY-MM-DD hh:mm:ss[.fraction]。前者取值范围为 1970-01-01 00:00:01.0000002038-01-19 03:14:07.999999,后者为 1000-01-01 00:00:00.0000009999-12-31 23:59:59.999999

在写入时,对于非法的日期时间值,将自动存成零值,即 '0000-00-00' 或 '0000-00-00 00:00:00'。

关于日期时间需要注意的点:

  • 因为 MySQL 支持比较宽松的格式来设置日期时间,所以理论上你可以用你想用的值来做为数字之间的分界符,但使用时需要关注其解析的原理。比如给一个日期格式的列设置 10:11:12,虽然这个值看起来像时间类型,但还是可以正确在被解析成目标列的格式,即日期。如果这这个日期列设置 10:45:15 则会认为是非法值,因为 45 不是一个合法的月份值,所以存储时变成零值 0000-00-00
  • 日期时间与毫秒的分界符必需是小数点。
  • 默认 MySQL 除了检查日月值是否有有效范围 1~ 31,1~12。还会将两者结合进来检查,比如 4 月没有 31。所以对于日期 2004-04-31 算是非法的,会变成零值 0000-00-00。如果不需要这样的约束检查,可开启 MySQL 的 ALLOW_INVALID_DATES 模式。

日期时间的自动初始化及更新

TIMESTAMPDATETIME 还支持自动初始化(auto-initialized)和更新到当前时间(auto-updated)。

  • 创建表定义列时,指定 DEFAULT CURRENT_TIMESTAMP 来使相应的日期时间列自动初始化。
  • 指定 ON UPDATE CURRENT_TIMESTAMP 来使相应的日期时间列自动更新。

两者可同时作用于一个日期时间列,表示插入记录时自动初始化成当前时间,后续记录更新时自动更新到当前时间。

其中 CURRENT_TIMESTAMP 指代当前时间,与其有相同效果的还有 CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP 以及 LOCALTIMESTAMP()

DEFAULT 除了可指定成当前时间外,也可指定一个任意的固定值,比如 DEFAULT 0 或 `DEFAULT '2000-01-01 00:00:00'。

对于指定了自动初始化的列,插入时如果没指定该列的值,则会自动设置为当前的时间。

对于指定为自动更新的列,一旦一条记录中有字段变更,该日期会自动更新成变更时的时间。如果不想它更新,可在插入其他值时手动设置一下该日期列为原有的值,让其保持不变。

TIMESTAMPDATETIME 在列的定义时,如果指定了小数部分,那么在配合使用 CURRENT_TIMESTAMP(fsp) 时,这个小数部分的精度需要保持一致。比如:

-- ✅
CREATE TABLE t1 (
ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
); --

MySQL 中的日期时间类型的更多相关文章

  1. MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP

    MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...

  2. MySQL学习分享-->日期时间类型

    日期时间类型 ①如果要用来表示年月日时分秒,一般使用datetime类型: ②如果要用来表示年月日,一般使用date类型: ③如果要表示时分秒,一般使用time类型: ④如果只是表示年份,一般使用ye ...

  3. MYSQL 中常用日期时间函数使用

    MySQL Date 函数 下面的表格列出了 MySQL 中最重要的内建日期函数: 函数 描述 NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 ...

  4. Mysql 中的日期时间字符串查询

    一.将数据库中的Date格式的数据,或者指定日期的字符串格式化为想要的样式 DATE_FORMAT (date, format)能根据格式串format 格式化日期或日期和时间值date,返回结果字符 ...

  5. mysql日期时间类型总结

    MySQL 日期类型:日期格式.所占存储空间.日期范围 比较.  日期类型        存储空间       日期格式                 日期范围  ------------ ---- ...

  6. Mysql 建表时,日期时间类型选择

    mysql(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示  D ...

  7. MySQL之日期时间类型

    mysql(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示  D ...

  8. 开发过程中 的一些 补充知识点 + 关于mysql中的日期和时间函数?

    参考: https://www.jb51.net/article/23966.htm https://yq.aliyun.com/articles/260389 mysql中的 日期格式是: HHHH ...

  9. Mysql 日期时间类型详解

    MySQL 中有多种数据类型可以用于日期和时间的表示,不同的版本可能有所差异,表3-2 中列出了MySQL 5.0 中所支持的日期和时间类型. 这些数据类型的主要区别如下: * 如果要用来表示年月日 ...

随机推荐

  1. python学习(十一)测试和调试

    最近学习了python的错误处理和几种测试方法 1 try except 可以通过try except方式捕捉异常 try: print('try...') r = 10/0 print('resul ...

  2. CentOS6.6安装heartbeat配置资源切换操作笔记实现高可用(原创)

    参考资料:http://www.centoscn.com/CentosServer/cluster/2015/0605/5604.html   背景需求: 使用heartbeat来做HA集群,并且把n ...

  3. 「Python」字符串操作内置函数

    目录: capitalize casefold center count encode decode endswith expandtabs find format format_map index ...

  4. (转)IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别

    本文来自:https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral,非常感谢 ...

  5. Global Vectors forWord Representation

    参考论文: GloVe: Global Vectors forWord Representation 参考博客:https://blog.csdn.net/coderTC/article/detail ...

  6. POJ 1228 Grandpa's Estate 凸包 唯一性

    LINK 题意:给出一个点集,问能否够构成一个稳定凸包,即加入新点后仍然不变. 思路:对凸包的唯一性判断,对任意边判断是否存在三点及三点以上共线,如果有边不满足条件则NO,注意使用水平序,这样一来共线 ...

  7. [php]禁用缓存

    header("Expires: -1"); header("Cache-Control: no_cache"); header("pragma: n ...

  8. 关于Java泛型深入理解小总结

    1.何为泛型 首先泛型的本质便是类型参数化,通俗的说就是用一个变量来表示类型,这个类型可以是String,Integer等等不确定,表明可接受的类型,原理类似如下代码 int pattern; //声 ...

  9. 51nod1110 距离之和最小 V3

    基准时间限制:1 秒 空间限制:131072 KB 分值: 40  X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上 ...

  10. 【CodeForces】901 B. GCD of Polynomials

    [题目]B. GCD of Polynomials [题意]给定n,要求两个最高次项不超过n的多项式(第一个>第二个),使得到它们GCD的辗转次数为n.n<=150. [算法]构造 [题解 ...