資料庫查詢中頻繁需要對時間欄位進行加減運算、格式化輸出、範圍篩選。本文聚焦 MySQL 核心時間函數 DATE_ADD()、DATE_SUB()、DATE_FORMAT(),提供豐富實戰範例,並補充常用時間型別選擇建議。
DATE_ADD(date, INTERVAL expr unit)
DATE_SUB(date, INTERVAL expr unit)
unit 支援單位:SECOND、MINUTE、HOUR、DAY、WEEK、MONTH、QUARTER、YEAR 等。
-- 查詢並顯示 start 時間及其翌日
SELECT START, DATE_ADD(START, INTERVAL 1 DAY) AS addStart
FROM ts_tickey WHERE id='373';
-- 更新資料:將 start 時間往後推一天
UPDATE ts_tickey
SET START = DATE_ADD(START, INTERVAL 1 DAY)
WHERE id='373';
-- 減少一天(負數 INTERVAL)
SELECT DATE_ADD(NOW(), INTERVAL -1 DAY) AS yesterday;
-- 增加 1 個月、1 年、1 小時
SELECT DATE_ADD(NOW(), INTERVAL 1 MONTH);
SELECT DATE_ADD(NOW(), INTERVAL 1 YEAR);
SELECT DATE_ADD(NOW(), INTERVAL 1 HOUR);

-- 以下語法等效
DATE_ADD(date, INTERVAL 1 DAY)
date + INTERVAL 1 DAY
DATE_SUB(date, INTERVAL 1 DAY)
date - INTERVAL 1 DAY
DATE_FORMAT(date, format)
| 符號 | 含義 | 範例輸出 |
|---|---|---|
| %Y | 四位數年份 | 2024 |
| %y | 兩位數年份 | 24 |
| %m | 月份 (01-12) | 01 |
| %c | 月份 (1-12) | 1 |
| %d | 日期 (01-31) | 05 |
| %e | 日期 (1-31) | 5 |
| %H | 小時 24制 (00-23) | 14 |
| %h/%I | 小時 12制 (01-12) | 02 |
| %i | 分鐘 (00-59) | 30 |
| %s/%S | 秒 (00-59) | 45 |
| %W | 星期名稱 | Monday |
| %a | 星期縮寫 | Mon |
-- 標準日期格式
SELECT DATE_FORMAT(a.start, '%Y-%m-%d') AS start_date FROM orders;
-- 日期時間完整格式
SELECT DATE_FORMAT(a.start, '%Y-%m-%d %H:%i:%s') AS start_datetime FROM orders;
-- 僅時間部分
SELECT DATE_FORMAT(a.uploadDate, '%H:%i:%s') AS upload_time FROM docs;
-- 中文友好格式
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H時%i分') AS cn_format;
| 函數 | 用途 | 範例 |
|---|---|---|
| NOW() | 當前日期時間 | 2024-01-15 14:30:45 |
| CURDATE() | 當前日期 | 2024-01-15 |
| CURTIME() | 當前時間 | 14:30:45 |
| UNIX_TIMESTAMP() | 時間戳轉換 | 1705300245 |
| FROM_UNIXTIME() | 時間戳轉日期 | 2024-01-15 14:30:45 |
| DATEDIFF(d1,d2) | 日期差天數 | DATEDIFF('2024-01-15','2024-01-10')=5 |
| TIMESTAMPDIFF(unit,d1,d2) | 精確時間差 | TIMESTAMPDIFF(HOUR, d1, d2) |
| LAST_DAY(date) | 該月最後一天 | 2024-01-31 |
| QUARTER(date) | 季度 (1-4) | 1 |
| WEEK(date) | 週數 | 3 |
| 型別 | 儲存大小 | 範圍 | 適用場景 |
|---|---|---|---|
| DATE | 3 bytes | 1000-01-01 ~ 9999-12-31 | 純日期(生日、紀念日) |
| TIME | 3 bytes | -838:59:59 ~ 838:59:59 | 純時間(工時、時長) |
| DATETIME | 8 bytes | 1000-01-01 ~ 9999-12-31 | 通用日期時間,無時區轉換 |
| TIMESTAMP | 4 bytes | 1970-01-01 ~ 2038-01-19 | 需時區感知、自動更新欄位 |
| YEAR | 1 byte | 1901 ~ 2155 | 僅需年份 |
核心建議:DATETIME 適用大多數業務;TIMESTAMP 適合跨時區應用且需自動維護 ON UPDATE CURRENT_TIMESTAMP;注意 TIMESTAMP 2038 年上限問題。
-- 查看當前時區
SHOW VARIABLES LIKE '%time_zone%';
-- 會話級設定時區
SET time_zone = '+08:00';
SET time_zone = 'Asia/Taipei';
-- 轉換時區顯示
SELECT CONVERT_TZ(NOW(), '+00:00', '+08:00');
MySQL 時間函數體系完善,DATE_ADD/SUB 處理運算,DATE_FORMAT 掌握輸出,配合正確的時間型別選擇,能解決 95% 以上的時間處理需求。建立統一的時間處理規範(如:存儲用 UTC、顯示用本地時區、格式化統一用 %Y-%m-%d %H:%i:%s),能有效避免時區混亂與格式不一致問題。