MySQL 中有多种数据类型可以用于日期和时间的表示,以下为 MySQL5.7 之后的日期和时间类型。
日期和时间类型 | 字节 | 零值 | 最小值 | 最大值 |
---|---|---|---|---|
DATE | 4 | 0000-00-00 | 1000-01-01 | 9999-12-31 |
DATETIME | 8 | 0000-00-00 00:00:00:00 | 1000-01-01 00:00:00 | 9999-12-31 23:59:59 |
TIMESTAMP | 4 | 00000000000000 | 19700101080001 | 2038 年的某个时刻 |
TIME | 3 | 00:00:00 | -838:59:59 | 838:59:59 |
YEAR | 1 | 0000 | 1901 | 2155 |
- 如果要用来表示年月日,通常用 DATE 来表示
- 如果要表示年月日时分秒,通常用 DATETIME 或 TIMESTAMP 来表。
- 如果只用来表示时分秒则用 TIME 来表示
- 如果只表示年份则用 YEAR
DATE,TIME,DATETIME
1 | # 创建新的数据表 |
TIMESTAMP
按照《深入浅出 MySQL 第三版》上的描述,创建字段时系统会为 TIMESTAMP 类型的字段添加NOT NULL
和ON UPDATE CURRENT_TIMSTAMP
约束。但经过我个人测试(MySQL8.0.21)并没有自动添加,于是我手动加了on update CURRENT_TIMESTAMP
。
刚刚查得 mysql8.0.2 开始,属性explicit_defaults_for_timestamp
默认为on
,这个配置不会自动设置默认值
,not null
,ON UPDATE CURRENT_TIMSTAMP
,使用set explicit_defaults_for_timestamp = off
开启配置
MySQL5.6 之前每个表中只能有一列字段的默认值为current_timestamp
。
1 | alter table t1 modify ts timestamp on update CURRENT_TIMESTAMP; |
下面做一个实验
1 | # 查看默认时区设置,默认应为SYSTEM,既是同步系统时区,如果在中国应该为东八区 |
因此可以得出结论:TIMESTAMP 会在插入日期时将其转换为本地时区,从数据库查询时再将日期转换为本地时区后显示,因此,不同地区的用户看到的同一个日期可能是不一样的。
另外,超出可储存的上限值(溢出)会被重置为 0 值,这个例子不进行演示了。
YEAR
YEAR 类型主要用来表示年份。
- 00 到 69 会被自动转化为 2000~2069 范围的 YEAR 值
- 70 到 99 会被自动转化为 1970~1999 范围的 YEAR 值
- 日期格式允许不严格语法,任意标点都允许做日期或时间的分隔符
- YYYYMMDDHHMMSS 或 YYMMDDHHMMSS 格式的数字,嘉定数字对于日期类型是有意义的。例如 19830905132800 和 830905132800 都被解释为 1983-09-05 13:28:00。数字值为 6、8、12、14 位长。如果一个值为 8 或 14 位长,则假定为 YYYYMMDD 或 YYYYMMDDHHMMSS 格式,前四位数表示年。如果数字是 6 或 12 位长,则假定为 YYMMDD 或 YYMMDDHHMMSS 格式,前两位表示年。其他数字被解释为仿佛用零填充到了最近的长度。
- 函数范围得结果,适合 DATETIME,DATE,TIME 或 TIMESTAMP 上下文,例如 NOW()或 CURRENT_DATE。