日期函数
在日常开发中,我们经常需要对日期进行加减运算或计算两个日期之间的差值。
MySQL 内置了一些非常实用的日期函数,比如 DATE_SUB、DATE_ADD、DATEDIFF、TIMESTAMPDIFF。本文将系统地梳理这些函数的用法和区别。
1. DATE_SUB
Section titled “1. DATE_SUB”在日常开发中,我们经常需要对日期进行“往前推”的操作,比如查询某个日期前一天的数据、某个时间段之前的订单。这时候就可以使用 MySQL 内置函数 DATE_SUB。
1.1. 基本语法
Section titled “1.1. 基本语法”DATE_SUB(date, INTERVAL expr unit)-
date:要操作的日期(可以是字符串日期,也可以是字段或参数)
-
expr:要减去的数值
-
unit:时间单位,比如 DAY、MONTH、YEAR、HOUR、MINUTE、SECOND
1.2. 示例
Section titled “1.2. 示例”-- 当前日期减去 1 天SELECT DATE_SUB('2025-09-09', INTERVAL 1 DAY);-- 结果:2025-09-08
-- 当前日期减去 2 个月SELECT DATE_SUB('2025-09-09', INTERVAL 2 MONTH);-- 结果:2025-07-09
-- 当前时间减去 30 分钟SELECT DATE_SUB('2025-09-09 10:00:00', INTERVAL 30 MINUTE);-- 结果:2025-09-09 09:30:001.3. 应用场景
Section titled “1.3. 应用场景”- 报表统计:查询“昨天”的数据
SELECT * FROM ordersWHERE created_time >= DATE_SUB(CURDATE(), INTERVAL 1 DAY);-
过期提醒:判断用户会员是否在 30 天内过期
-
时间区间查询:某日期前 N 天的数据
DATE_SUB是一个非常实用的日期函数,适合用来做时间回溯,经常搭配NOW()、CURDATE()一起使用。
2. DATE_ADD
Section titled “2. DATE_ADD”如果说 DATE_SUB 是往前推日期,那 DATE_ADD 则是往后推日期。在实际业务中,比如计算到期时间、预计完成时间,就会用到 DATE_ADD。
2.1. 基本语法
Section titled “2.1. 基本语法”DATE_ADD(date, INTERVAL expr unit)-
date:基准日期
-
expr:要增加的数值
-
unit:时间单位(DAY、MONTH、YEAR、HOUR、MINUTE、SECOND)
2.2. 示例
Section titled “2.2. 示例”-- 当前日期加 1 天SELECT DATE_ADD('2025-09-09', INTERVAL 1 DAY);-- 结果:2025-09-10
-- 当前日期加 1 年SELECT DATE_ADD('2025-09-09', INTERVAL 1 YEAR);-- 结果:2026-09-09
-- 当前时间加 2 小时SELECT DATE_ADD('2025-09-09 08:00:00', INTERVAL 2 HOUR);-- 结果:2025-09-09 10:00:002.3. 应用场景
Section titled “2.3. 应用场景”-
订单到期日:下单时间 + 7 天 = 预计送达日
-
会员到期:注册时间 + 1 年 = 会员有效期
-
活动时间:开始时间 + 3 天 = 活动结束时间
DATE_ADD是DATE_SUB的兄弟函数,一个加、一个减。开发中经常成对出现,用来做时间区间的计算。
3. DATEDIFF
Section titled “3. DATEDIFF”在业务场景中,我们经常需要知道两个日期之间相差多少天。MySQL 提供的 DATEDIFF 就是专门用来计算“日期差”的函数。
3.1. 基本语法
Section titled “3.1. 基本语法”DATEDIFF(date1, date2)-
返回结果 =
date1 - date2的天数差 -
只计算天数,忽略时间部分
3.2. 示例
Section titled “3.2. 示例”-- 计算相差的天数SELECT DATEDIFF('2025-09-09', '2025-09-01');-- 结果:8
-- 如果顺序相反SELECT DATEDIFF('2025-09-01', '2025-09-09');-- 结果:-83.3. 应用场景
Section titled “3.3. 应用场景”-
倒计时:距离活动结束还有多少天
-
订单时效:订单完成用了多少天
-
工期管理:任务起始时间与截止时间的天数差
SELECT order_id, DATEDIFF(delivery_date, created_time) AS days_usedFROM orders;
DATEDIFF非常适合计算两个日期的天数差,如果需要让两个日期在指定单位下的差计算差值,就要用TIMESTAMPDIFF。
4. TIMESTAMPDIFF
Section titled “4. TIMESTAMPDIFF”如果你觉得 DATEDIFF 只能算天数还不够用,那么 TIMESTAMPDIFF 就是增强版。它允许指定单位,灵活计算日期差。
4.1. 基本语法
Section titled “4.1. 基本语法”TIMESTAMPDIFF(unit, datetime1, datetime2)-
unit:返回差值的单位(YEAR、MONTH、DAY、HOUR、MINUTE、SECOND)
-
datetime1、datetime2:要比较的时间
4.2. 示例
Section titled “4.2. 示例”-- 计算两个日期相差多少天SELECT TIMESTAMPDIFF(DAY, '2025-09-01 12:00:00', '2025-09-09 12:00:00');-- 结果:8
-- 相差的小时数SELECT TIMESTAMPDIFF(HOUR, '2025-09-01 12:00:00', '2025-09-02 12:00:00');-- 结果:24
-- 相差的分钟数SELECT TIMESTAMPDIFF(MINUTE, '2025-09-01 12:00:00', '2025-09-01 13:00:00');-- 结果:60
-- 相差的月份数SELECT TIMESTAMPDIFF(MONTH, '2025-01-01', '2025-09-01');-- 结果:84.3. 应用场景
Section titled “4.3. 应用场景”-
活跃度分析:用户最后登录距今多少天
-
在线时长:登录时间和登出时间的差值(分钟/小时)
-
统计分析:订单平均处理耗时(小时/天/月)
TIMESTAMPDIFF是日期差计算的利器,可以指定精确到 年、月、日、时、分、秒,比DATEDIFF灵活得多。
5. 当前时间与日期函数
Section titled “5. 当前时间与日期函数”在开发中,我们经常需要获取当前的日期、时间或完整时间戳,比如记录日志时间、生成报表日期、标记创建时间等。
5.1. 常用函数与说明
Section titled “5.1. 常用函数与说明”| 函数 | 说明 | 示例结果 |
|---|---|---|
NOW() | 返回当前日期和时间(精确到秒) | 2025-10-07 09:32:18 |
CURDATE() | 返回当前日期(不含时间) | 2025-10-07 |
CURTIME() | 返回当前时间(不含日期) | 09:32:18 |
SYSDATE() | 返回执行函数瞬间的系统时间(每次调用可能不同) | 动态变化 |
5.2. 示例
Section titled “5.2. 示例”SELECT NOW(), CURDATE(), CURTIME(), SYSDATE();5.3. 应用场景
Section titled “5.3. 应用场景”-
记录系统操作时间、日志时间戳
-
生成当日报表
-
默认插入时间字段(如
create_time、update_time)
6. 日期提取函数
Section titled “6. 日期提取函数”用于从日期时间中提取特定部分(年、月、日、小时等),常用于时间维度分析或条件筛选。
| 函数 | 说明 | 示例('2025-10-07 09:32:18') |
|---|---|---|
YEAR(date) | 提取年份 | 2025 |
MONTH(date) | 提取月份 | 10 |
DAY(date) / DAYOFMONTH(date) | 提取日期(1–31) | 7 |
HOUR(date) | 提取小时 | 9 |
MINUTE(date) | 提取分钟 | 32 |
SECOND(date) | 提取秒 | 18 |
DAYOFWEEK(date) | 获取星期几(1=周日) | 3 |
WEEKDAY(date) | 获取星期几(0=周一) | 1 |
DAYOFYEAR(date) | 获取一年中的第几天 | 280 |
QUARTER(date) | 获取第几季度(1–4) | 4 |
7. 日期格式化与解析函数
Section titled “7. 日期格式化与解析函数”这些函数负责日期与字符串之间的互转,常用于展示格式控制、字符串日期解析。
7.1. DATE_FORMAT() —— 日期转字符串
Section titled “7.1. DATE_FORMAT() —— 日期转字符串”将日期类型格式化为指定格式的字符串。
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');-- 返回:2025-10-07 09:32:18常用格式符:
| 格式符 | 含义 | 示例 |
|---|---|---|
%Y | 四位年份 | 2025 |
%m | 两位月份 | 10 |
%d | 两位日期 | 07 |
%H | 小时(24小时制) | 09 |
%i | 分钟 | 32 |
%s | 秒 | 18 |
%W | 星期全称 | Tuesday |
%M | 月份英文名 | October |
7.2. STR_TO_DATE() —— 字符串转日期
Section titled “7.2. STR_TO_DATE() —— 字符串转日期”按指定格式将字符串解析成日期类型。
SELECT STR_TO_DATE('07/10/2025', '%d/%m/%Y');-- 返回:2025-10-078. 时间戳函数
Section titled “8. 时间戳函数”时间戳函数实现日期与 Unix 时间戳之间的相互转换。
| 函数 | 说明 | 示例 |
|---|---|---|
UNIX_TIMESTAMP() | 获取当前时间戳(秒) | 1759810338 |
UNIX_TIMESTAMP(date) | 指定日期转时间戳 | UNIX_TIMESTAMP('2025-10-07 09:32:18') |
FROM_UNIXTIME(ts) | 时间戳转日期 | FROM_UNIXTIME(1759810338) → 2025-10-07 09:32:18 |
9. 复合日期函数
Section titled “9. 复合日期函数”这类函数可以生成或计算更复杂的日期逻辑,比如“当月最后一天”、“计算月份差”等。
| 函数 | 说明 | 示例 |
|---|---|---|
LAST_DAY(date) | 返回指定日期所在月的最后一天 | LAST_DAY('2025-02-15') → 2025-02-28 |
MAKEDATE(year, day_of_year) | 根据年份与年内天数构造日期 | MAKEDATE(2025, 100) → 2025-04-10 |
MAKETIME(h,m,s) | 构造时间 | MAKETIME(9,30,0) → '09:30:00' |
EXTRACT(unit FROM date) | 提取指定部分(年/月/日/小时等) | EXTRACT(YEAR FROM NOW()) → 2025 |
PERIOD_DIFF(p1, p2) | 计算两个 YYYYMM 期间相差的月份数 | PERIOD_DIFF(202510, 202309) → 13 |
10. 日期区间与条件筛选
Section titled “10. 日期区间与条件筛选”日期函数常用于查询条件,快速筛选某时间段内的数据。
-- 最近 30 天的订单SELECT *FROM ordersWHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 2025 年 10 月的销售记录SELECT *FROM salesWHERE YEAR(order_date)=2025 AND MONTH(order_date)=10;