MySQL 提供豐富的日期時間函數族群,支援從當前時間獲取、成分提取、時區轉換到複雜日曆計算。本文為三部曲第一部分,奠定核心函數基礎。
SELECT NOW();
-- 2023-10-15 14:30:45
同義詞(完全等價):
CURRENT_TIMESTAMP() / CURRENT_TIMESTAMPLOCALTIME() / LOCALTIMELOCALTIMESTAMP() / LOCALTIMESTAMP (5.6.4+)特性:語句執行開始時固定值,語句內多次呼叫返回相同值。
SELECT NOW(), SLEEP(3), NOW(); -- 兩次 NOW() 相同
SELECT SYSDATE(), SLEEP(3), SYSDATE(); -- 兩次相差 3 秒
差異:SYSDATE() 執行瞬間取值,NOW() 語句開始取值。複製場景下 SYSDATE() 可能導致主從不一致,建議啟用 --sysdate-is-now 或避免使用。
SELECT CURDATE(); -- 2023-10-15 (同義: CURRENT_DATE, CURRENT_DATE())
SELECT CURTIME(); -- 14:30:45 (同義: CURRENT_TIME, CURRENT_TIME())
SELECT
UTC_TIMESTAMP() AS utc_dt, -- 2023-10-15 06:30:45
UTC_DATE() AS utc_d, -- 2023-10-15
UTC_TIME() AS utc_t, -- 06:30:45
NOW() AS local_dt; -- 2023-10-15 14:30:45 (假設 UTC+8)
業務涉及多時區時,統一儲存 UTC,應用層按用戶時區顯示。
設定測試變數:SET @dt = '2023-10-15 14:30:45.123456';
| 函數 | 範例結果 | 說明 |
|---|---|---|
DATE(@dt) | 2023-10-15 | 日期部分 |
TIME(@dt) | 14:30:45.123456 | 時間部分(含微秒) |
YEAR(@dt) | 2023 | 年 |
QUARTER(@dt) | 4 | 季度 (1-4) |
MONTH(@dt) | 10 | 月 (1-12) |
WEEK(@dt) | 41 | 週數 (0-53,模式依 default_week_format) |
DAY(@dt) | 15 | 月內天數 (1-31) |
HOUR(@dt) | 14 | 時 (0-23) |
MINUTE(@dt) | 30 | 分 (0-59) |
SECOND(@dt) | 45 | 秒 (0-59) |
MICROSECOND(@dt) | 123456 | 微秒 (0-999999) |
SELECT
EXTRACT(YEAR FROM @dt), -- 2023
EXTRACT(QUARTER FROM @dt), -- 4
EXTRACT(MONTH FROM @dt), -- 10
EXTRACT(WEEK FROM @dt), -- 41
EXTRACT(DAY FROM @dt), -- 15
EXTRACT(HOUR FROM @dt), -- 14
EXTRACT(MINUTE FROM @dt), -- 30
EXTRACT(SECOND FROM @dt), -- 45
EXTRACT(MICROSECOND FROM @dt); -- 123456
-- 組合單位(強大特性)
SELECT
EXTRACT(YEAR_MONTH FROM @dt), -- 202310
EXTRACT(DAY_HOUR FROM @dt), -- 1514
EXTRACT(DAY_MINUTE FROM @dt), -- 151430
EXTRACT(DAY_SECOND FROM @dt), -- 15143045
EXTRACT(DAY_MICROSECOND FROM @dt);-- 15143045123456
優勢:單一函數涵蓋所有提取需求,組合單位可一次取得複合成分。
SET @d = '2023-10-15';
SELECT
DAYOFWEEK(@d), -- 1 (1=Sunday ... 7=Saturday)
DAYOFMONTH(@d), -- 15
DAYOFYEAR(@d); -- 288
SET @dt = NOW();
-- DATE_ADD / DATE_SUB (核心函數)
SELECT DATE_ADD(@dt, INTERVAL 1 DAY); -- +1天
SELECT DATE_ADD(@dt, INTERVAL -1 DAY); -- -1天 (等同 DATE_SUB)
SELECT DATE_ADD(@dt, INTERVAL '1 12:30:45' DAY_SECOND); -- +1天12時30分45秒
-- 簡寫函數(內部轉為 DATE_ADD)
SELECT ADDDATE(@dt, 1); -- +1天
SELECT ADDDATE(@dt, INTERVAL 1 MONTH);
SELECT SUBDATE(@dt, 1); -- -1天
-- 時間專用
SELECT ADDTIME(@dt, '12:30:45'); -- 增加時間
SELECT SUBTIME(@dt, '12:30:45'); -- 減少時間
| 單位 | 格式範例 | 說明 |
|---|---|---|
| MICROSECOND | 123456 | 微秒 |
| SECOND | 30 | 秒 |
| MINUTE | 30 | 分 |
| HOUR | 14 | 時 |
| DAY | 15 | 天 |
| WEEK | 2 | 週 |
| MONTH | 10 | 月 |
| QUARTER | 4 | 季 |
| YEAR | 2023 | 年 |
| SECOND_MICROSECOND | '30.123456' | 秒.微秒 |
| MINUTE_MICROSECOND | '30:30.123456' | 分:秒.微秒 |
| MINUTE_SECOND | '30:30' | 分:秒 |
| HOUR_MICROSECOND | '14:30:30.123456' | 時:分:秒.微秒 |
| HOUR_SECOND | '14:30:30' | 時:分:秒 |
| HOUR_MINUTE | '14:30' | 時:分 |
| DAY_MICROSECOND | '15 14:30:30.123456' | 天 時:分:秒.微秒 |
| DAY_SECOND | '15 14:30:30' | 天 時:分:秒 |
| DAY_MINUTE | '15 14:30' | 天 時:分 |
| DAY_HOUR | '15 14' | 天 時 |
| YEAR_MONTH | '2023-10' | 年-月 |
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'); -- 2023-10-15 14:30:45
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H時%i分'); -- 2023年10月15日 14時30分
常用格式符:%Y(4位年) %m(2位月) %d(2位日) %H(24制時) %i(分) %s(秒) %f(微秒) %W(星期全名) %M(月份全名)。
SELECT STR_TO_DATE('2023-10-15 14:30:45', '%Y-%m-%d %H:%i:%s');
SELECT STR_TO_DATE('15/10/2023', '%d/%m/%Y');
與 DATE_FORMAT 互為逆操作,ETL 清洗非標準日期字串必備。
掌握日期時間函數體系,能將複雜的業務時間邏輯(如「上個月最後一個工作日」、「下個季度首日」)下沉至 SQL 層,減少應用層代碼複雜度,提升查詢效能與可維護性。