MySQL 提供豐富的日期時間函數,涵蓋擷取、運算、格式化、轉換等場景。本文系統整理核心函數用法,並附上實戰範例,方便開發快速查閱。
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
DAYOFWEEK(date) | 星期索引 (1=週日...7=週六) | DAYOFWEEK('1998-02-03') | 3 |
WEEKDAY(date) | 星期索引 (0=週一...6=週日) | WEEKDAY('1997-10-04') | 5 |
DAYOFMONTH(date) | 月份中的日期 (1-31) | DAYOFMONTH('1998-02-03') | 3 |
DAYOFYEAR(date) | 年中的第幾天 (1-366) | DAYOFYEAR('1998-02-03') | 34 |
MONTH(date) | 月份 (1-12) | MONTH('1998-02-03') | 2 |
DAYNAME(date) | 星期名稱 | DAYNAME('1998-02-05') | Thursday |
MONTHNAME(date) | 月份名稱 | MONTHNAME('1998-02-05') | February |
QUARTER(date) | 季度 (1-4) | QUARTER('98-04-01') | 2 |
WEEK(date[,mode]) | 週數,mode=0 週日起算,1 週一起算 | WEEK('1998-02-20',1) | 8 |
YEAR(date) | 年份 (1000-9999) | YEAR('98-02-03') | 1998 |
HOUR(time) | 小時 (0-23) | HOUR('10:05:03') | 10 |
MINUTE(time) | 分鐘 (0-59) | MINUTE('10:05:03') | 5 |
SECOND(time) | 秒 (0-59) | SECOND('10:05:03') | 3 |
PERIOD_ADD(P,N):期間 P (格式 YYMM/YYYYMM) 加 N 月 → 回傳 YYYYMM。PERIOD_ADD(9801,2) → 199803PERIOD_DIFF(P1,P2):兩期間相差月數。PERIOD_DIFF(9802,199703) → 11語法:DATE_ADD(date, INTERVAL expr type),type 關鍵字對應格式如下:
| type | 意義 | expr 格式範例 |
|---|---|---|
| SECOND | 秒 | SECONDS |
| MINUTE | 分 | MINUTES |
| HOUR | 時 | HOURS |
| DAY | 天 | DAYS |
| MONTH | 月 | MONTHS |
| YEAR | 年 | YEARS |
| MINUTE_SECOND | 分:秒 | "MINUTES:SECONDS" |
| HOUR_MINUTE | 時:分 | "HOURS:MINUTES" |
| DAY_HOUR | 天 時 | "DAYS HOURS" |
| YEAR_MONTH | 年-月 | "YEARS-MONTHS" |
| HOUR_SECOND | 時:分:秒 | "HOURS:MINUTES:SECONDS" |
| DAY_MINUTE | 天 時:分 | "DAYS HOURS:MINUTES" |
| DAY_SECOND | 天 時:分:秒 | "DAYS HOURS:MINUTES:SECONDS" |
實用範例:
SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND; -- 1998-01-01 00:00:00
SELECT DATE_ADD('1997-12-31 23:59:59', INTERVAL 1 DAY); -- 1998-01-01 23:59:59
SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY); -- 1997-12-02
SELECT DATE_ADD('1998-01-01', INTERVAL '-1 10' DAY_HOUR); -- 1997-12-30 14:00:00
提示: INTERVAL 與 type 不分大小寫;若 expr 過短,MySQL 會假設左側高位缺失(如 DAY_SECOND 給 "1:10" 視同 MINUTE_SECOND)。
TO_DAYS(date):日期轉為第 0 年起算的天數(不適用 1582 年格里曆前)。FROM_DAYS(N):天數轉回 DATE。常用格式符號:
| 符號 | 意義 | 範例輸出 |
|---|---|---|
| %Y | 4 位年 | 1997 |
| %y | 2 位年 | 97 |
| %M | 月份全名 | January |
| %b | 月份縮寫 | Jan |
| %m | 月份 01-12 | 01 |
| %d | 日期 01-31 | 04 |
| %H | 24 制時 00-23 | 22 |
| %h/%I | 12 制時 01-12 | 10 |
| %i | 分鐘 00-59 | 23 |
| %s/%S | 秒 00-59 | 00 |
| %T | 24 制時間 hh:mm:ss | 22:23:00 |
| %r | 12 制時間 hh:mm:ss AM/PM | 10:23:00 PM |
| %W | 星期全名 | Saturday |
| %a | 星期縮寫 | Sat |
SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); -- Saturday October 1997
SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); -- 22:23:00
SELECT DATE_FORMAT('1997-10-04 22:23:00', '%D %y %a %d %m %b %j'); -- 4th 97 Sat 04 10 Oct 277
NOW() / SYSDATE() / CURRENT_TIMESTAMP:回傳 YYYY-MM-DD HH:MM:SS 或數值 YYYYMMDDHHMMSS。CURDATE() / CURRENT_DATE:回傳今日日期。CURTIME() / CURRENT_TIME:回傳當前時間。UNIX_TIMESTAMP([date]):無參數回傳當前秒數;有參數轉換指定日期時間為秒數(自 1970-01-01 UTC)。FROM_UNIXTIME(unix_timestamp[,format]):秒數轉回日期時間字串,可加格式化參數(同 DATE_FORMAT)。SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00'); -- 875996580
SELECT FROM_UNIXTIME(875996580); -- 1997-10-04 22:23:00
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x'); -- 格式化輸出
SEC_TO_TIME(seconds):秒數 → HH:MM:SS。TIME_TO_SEC(time):時間 → 總秒數。SELECT SEC_TO_TIME(2378); -- 00:39:38
SELECT TIME_TO_SEC('22:23:00'); -- 80580
SELECT * FROM `table`
WHERE TO_DAYS(NOW()) - TO_DAYS(`date_col`) <= 30;
善用這些函數,能讓 SQL 查詢更簡潔、效能更佳。建議搭配索引設計(如對日期欄建立索引),避免在 WHERE 條件中對欄位使用函數導致索引失效。