Skip to content

日期函数


在日常开发中,我们经常需要对日期进行加减运算或计算两个日期之间的差值。
MySQL 内置了一些非常实用的日期函数,比如 DATE_SUBDATE_ADDDATEDIFFTIMESTAMPDIFF。本文将系统地梳理这些函数的用法和区别。

在日常开发中,我们经常需要对日期进行“往前推”的操作,比如查询某个日期前一天的数据、某个时间段之前的订单。这时候就可以使用 MySQL 内置函数 DATE_SUB

DATE_SUB(date, INTERVAL expr unit)
  • date:要操作的日期(可以是字符串日期,也可以是字段或参数)

  • expr:要减去的数值

  • unit:时间单位,比如 DAY、MONTH、YEAR、HOUR、MINUTE、SECOND

-- 当前日期减去 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:00
  • 报表统计:查询“昨天”的数据
SELECT * FROM orders
WHERE created_time >= DATE_SUB(CURDATE(), INTERVAL 1 DAY);
  • 过期提醒:判断用户会员是否在 30 天内过期

  • 时间区间查询:某日期前 N 天的数据

DATE_SUB 是一个非常实用的日期函数,适合用来做时间回溯,经常搭配 NOW()CURDATE() 一起使用。


如果说 DATE_SUB 是往前推日期,那 DATE_ADD 则是往后推日期。在实际业务中,比如计算到期时间、预计完成时间,就会用到 DATE_ADD

DATE_ADD(date, INTERVAL expr unit)
  • date:基准日期

  • expr:要增加的数值

  • unit:时间单位(DAY、MONTH、YEAR、HOUR、MINUTE、SECOND)

-- 当前日期加 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:00
  • 订单到期日:下单时间 + 7 天 = 预计送达日

  • 会员到期:注册时间 + 1 年 = 会员有效期

  • 活动时间:开始时间 + 3 天 = 活动结束时间

DATE_ADDDATE_SUB 的兄弟函数,一个加、一个减。开发中经常成对出现,用来做时间区间的计算。


在业务场景中,我们经常需要知道两个日期之间相差多少天。MySQL 提供的 DATEDIFF 就是专门用来计算“日期差”的函数。

DATEDIFF(date1, date2)
  • 返回结果 = date1 - date2 的天数差

  • 只计算天数,忽略时间部分

-- 计算相差的天数
SELECT DATEDIFF('2025-09-09', '2025-09-01');
-- 结果:8
-- 如果顺序相反
SELECT DATEDIFF('2025-09-01', '2025-09-09');
-- 结果:-8
  • 倒计时:距离活动结束还有多少天

  • 订单时效:订单完成用了多少天

  • 工期管理:任务起始时间与截止时间的天数差

SELECT order_id,
DATEDIFF(delivery_date, created_time) AS days_used
FROM orders;

DATEDIFF 非常适合计算两个日期的天数差,如果需要让两个日期在指定单位下的差计算差值,就要用 TIMESTAMPDIFF


如果你觉得 DATEDIFF 只能算天数还不够用,那么 TIMESTAMPDIFF 就是增强版。它允许指定单位,灵活计算日期差。

TIMESTAMPDIFF(unit, datetime1, datetime2)
  • unit:返回差值的单位(YEAR、MONTH、DAY、HOUR、MINUTE、SECOND)

  • datetime1datetime2:要比较的时间

-- 计算两个日期相差多少天
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');
-- 结果:8
  • 活跃度分析:用户最后登录距今多少天

  • 在线时长:登录时间和登出时间的差值(分钟/小时)

  • 统计分析:订单平均处理耗时(小时/天/月)

TIMESTAMPDIFF 是日期差计算的利器,可以指定精确到 年、月、日、时、分、秒,比 DATEDIFF 灵活得多。

在开发中,我们经常需要获取当前的日期、时间或完整时间戳,比如记录日志时间、生成报表日期、标记创建时间等。

函数说明示例结果
NOW()返回当前日期和时间(精确到秒)2025-10-07 09:32:18
CURDATE()返回当前日期(不含时间)2025-10-07
CURTIME()返回当前时间(不含日期)09:32:18
SYSDATE()返回执行函数瞬间的系统时间(每次调用可能不同)动态变化
SELECT NOW(), CURDATE(), CURTIME(), SYSDATE();
  • 记录系统操作时间、日志时间戳

  • 生成当日报表

  • 默认插入时间字段(如 create_timeupdate_time

用于从日期时间中提取特定部分(年、月、日、小时等),常用于时间维度分析或条件筛选。

函数说明示例('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.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
%s18
%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-07

时间戳函数实现日期与 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

这类函数可以生成或计算更复杂的日期逻辑,比如“当月最后一天”、“计算月份差”等。

函数说明示例
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

日期函数常用于查询条件,快速筛选某时间段内的数据。

-- 最近 30 天的订单
SELECT *
FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 2025 年 10 月的销售记录
SELECT *
FROM sales
WHERE YEAR(order_date)=2025
AND MONTH(order_date)=10;