日期时间类型
约 890 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › MySQL › 数据类型与约束(在新窗口打开) › 日期时间类型
MySQL 提供了五种日期时间类型,涵盖只存日期、只存时间、同时存日期时间、以及时间戳四种场景。
类型一览
| 类型 | 占用字节 | 格式 | 范围 | 用途 |
|---|---|---|---|---|
DATE | 3 | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 | 生日、入职日期 |
TIME | 3 | HH:MM:SS | -838:59:59 ~ 838:59:59 | 时长、营业时间 |
DATETIME | 5~8 | YYYY-MM-DD HH:MM:SS | 1000-01-01 ~ 9999-12-31 | 通用时间记录 |
TIMESTAMP | 4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 ~ 2038-01-19 | 跨时区场景 |
YEAR | 1 | YYYY | 1901 ~ 2155 | 年度统计 |
DATETIME 与 TIMESTAMP 的区别
这是最常混淆的一组类型,核心差异在时区敏感度和范围。
CREATE TABLE time_demo (
dt DATETIME,
ts TIMESTAMP
);
-- 先检查时区
SELECT @@session.time_zone; -- 通常为 SYSTEM
-- 插入相同值
INSERT INTO time_demo VALUES ('2026-05-15 12:00:00', '2026-05-15 12:00:00');在不同时区查询时的差异:
-- 在 UTC+8 下查询,两者一致
SELECT * FROM time_demo;
-- dt: 2026-05-15 12:00:00
-- ts: 2026-05-15 12:00:00
-- 改为 UTC 时区后再查询
SET time_zone = '+00:00';
SELECT * FROM time_demo;
-- dt: 2026-05-15 12:00:00 (不变)
-- ts: 2026-05-15 04:00:00 (减8小时,因为 MySQL 内部存的是 UTC)| 差异点 | DATETIME | TIMESTAMP |
|---|---|---|
| 时区 | 不受时区影响,存什么就显示什么 | 受时区影响,内部存 UTC,查询时转当前时区 |
| 范围 | 1000 ~ 9999 年 | 1970 ~ 2038 年(2038 年问题) |
| 占用 | 5~8 字节(取决于小数秒精度) | 4 字节 |
| 默认值 | MySQL 5.6.5 前不支持 | 默认 CURRENT_TIMESTAMP |
选择建议:如果你的应用在全球多时区使用(如国际站),用
TIMESTAMP让 MySQL 自动做时区转换;如果业务场景不关心时区(如记录银行本地交易时间),用DATETIME。
小数秒精度
MySQL 5.6.3+ 支持微秒精度,类型名后加括号指定小数位数:
CREATE TABLE micro (
t DATETIME(3), -- 毫秒精度
ts TIMESTAMP(6) -- 微秒精度
);
INSERT INTO micro VALUES ('2026-05-15 12:00:00.123', '2026-05-15 12:00:00.123456');自动初始化和自动更新
MySQL 支持用 DEFAULT 和 ON UPDATE 自动处理时间字段:
CREATE TABLE article (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
INSERT INTO article (title) VALUES ('MySQL 入门');
SELECT created_at, updated_at FROM article;
-- 两者都为插入时间
-- 更新行
UPDATE article SET title = 'MySQL 入门(修订)' WHERE id = 1;
SELECT updated_at FROM article;
-- updated_at 自动更新为当前时间
ON UPDATE CURRENT_TIMESTAMP在行记录的任何列被修改时都会刷新该字段。适用于记录「最后更新时间」。
常用日期函数
-- 当前日期时间
SELECT NOW(), CURDATE(), CURTIME();
-- 提取年/月/日
SELECT YEAR('2026-05-15'), MONTH('2026-05-15'), DAY('2026-05-15');
-- 结果: 2026, 5, 15
-- 日期加减
SELECT DATE_ADD('2026-05-15', INTERVAL 7 DAY);
-- 结果: 2026-05-22
SELECT DATE_SUB('2026-05-15', INTERVAL 1 MONTH);
-- 结果: 2026-04-15
-- 计算日期差
SELECT DATEDIFF('2026-12-31', '2026-05-15');
-- 结果: 230
-- 格式化
SELECT DATE_FORMAT('2026-05-15 14:30:00', '%Y年%m月%d日 %H:%i');
-- 结果: 2026年05月15日 14:30小结
DATE只存日期,DATETIME存完整日期时间且不受时区影响,TIMESTAMP受时区影响但有 2038 年限制。- 多时区场景优先用
TIMESTAMP;单一时区或不关心时区用DATETIME。 DEFAULT CURRENT_TIMESTAMP+ON UPDATE CURRENT_TIMESTAMP是记录创建时间和更新时间的通用写法。- 日期函数
DATE_ADD、DATEDIFF、DATE_FORMAT等能满足绝大多数日期计算需求。
