首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 日期時間函數大全:分類詳解與實戰範例

     編輯:MySQL 資料庫相關知識

前言

MySQL 提供豐富的日期時間函數族,支援日期提取、運算、格式化、轉換等多維度操作。本文按功能分類整理 23 大核心函數,附帶語法、參數說明與實戰範例,作為開發與調優的速查手冊。

一、日期組件提取函數

函數功能返回值範圍/示例
DAYOFWEEK(date)週索引(1=周日,7=周六),符合 ODBC 標準DAYOFWEEK('1998-02-03') → 3
WEEKDAY(date)週索引(0=周一,6=周日)WEEKDAY('1997-10-04') → 5
DAYOFMONTH(date)月內天數1~31
DAYOFYEAR(date)年內天數1~366
MONTH(date)月份1~12
DAYNAME(date)星期英文名'Thursday'
MONTHNAME(date)月份英文名'February'
QUARTER(date)季度1~4
WEEK(date[,mode])周數,mode=0 週日起算,mode=1 週一起算WEEK('1998-02-20',1) → 8
YEAR(date)年份(4 位)1000~9999
HOUR(time)小時0~23
MINUTE(time)分鐘0~59
SECOND(time)秒0~59

二、周期運算函數

函數功能示例
PERIOD_ADD(P,N)期間 P(YYMM/YYYYMM)加 N 月PERIOD_ADD(9801,2) → 199803
PERIOD_DIFF(P1,P2)兩期間月份差PERIOD_DIFF(9802,199703) → 11

注意: 期間參數非日期類型,僅用於月度統計場景(如財務報表)。

三、日期加減運算:DATE_ADD / DATE_SUB / ADDDATE / SUBDATE

四個函數功能等價,推薦使用 DATE_ADD/DATE_SUB 語義更清晰。MySQL 3.23+ 支援 +/- 運算符重載。

INTERVAL 類型與表達式格式對照表

類型關鍵字含義expr 格式示例
SECOND / MINUTE / HOUR / DAY / MONTH / YEAR單一單位30、6
MINUTE_SECOND分:秒'1:30'
HOUR_MINUTE時:分'2:30'
DAY_HOUR天 時'3 12'
YEAR_MONTH年-月'2-6'
HOUR_SECOND時:分:秒'1:30:45'
DAY_MINUTE天 時:分'3 12:30'
DAY_SECOND天 時:分:秒'3 12:30:45'

實戰範例

-- 日期加 1 秒
SELECT DATE_ADD('1997-12-31 23:59:59', INTERVAL 1 SECOND);  -- 1998-01-01 00:00:00

-- 日期加 1 天
SELECT '1997-12-31' + INTERVAL 1 DAY;  -- 1998-01-01

-- 複合間隔:減去 1 天 1 時 1 分 1 秒
SELECT DATE_SUB('1998-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND);  -- 1997-12-30 22:58:59

-- 負間隔:減去 1 天 10 小時
SELECT DATE_ADD('1998-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);  -- 1997-12-30 14:00:00

-- 月末自動調整:1月30日加1個月→2月28日(非閏年)
SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);  -- 1998-02-28

-- 提取組件
SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');  -- 199907

關鍵行為說明

  • expr 格式過短時,MySQL 假定省略高位(如 '1:10' DAY_SECOND 視為 MINUTE_SECOND)
  • 日期無效返回 NULL
  • 月份加減導致日期超出目標月最大天數時,自動調整為該月最後一天
  • INTERVAL 關鍵字與類型不區分大小寫

四、天數與日期互轉:TO_DAYS / FROM_DAYS

SELECT TO_DAYS('1997-10-07');   -- 729669(從 Year 0 起算天數)
SELECT FROM_DAYS(729669);       -- '1997-10-07'

限制: 僅適用於格里曆(1582 年後),早期日期不可用。

五、日期格式化:DATE_FORMAT / TIME_FORMAT

常用格式符速查

符號含義示例
%Y / %y4位/2位年份1997 / 97
%m / %c月份(01~12 / 1~12)02 / 2
%d / %e日期(01~31 / 1~31)03 / 3
%H / %k小時(00~23 / 0~23)22 / 22
%i分鐘(00~59)23
%S / %s秒(00~59)00
%W / %a星期全稱/縮寫Saturday / Sat
%M / %b月份全稱/縮寫October / Oct
%r / %T12h/24h 時間10:23:00 PM / 22:23:00
%pAM/PMPM
%j年內天數(001~366)277

TIME_FORMAT 僅支援時分秒相關符號,其他符號返回 NULL/0。

範例

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'

六、當前日期時間獲取

函數返回格式(字符串/數字上下文)別名
CURDATE()'YYYY-MM-DD' / YYYYMMDDCURRENT_DATE
CURTIME()'HH:MM:SS' / HHMMSSCURRENT_TIME
NOW()'YYYY-MM-DD HH:MM:SS' / YYYYMMDDHHMMSSSYSDATE()、CURRENT_TIMESTAMP

注意: NOW() 在存儲過程/觸發器中執行開始時固定;SYSDATE() 實時獲取,主從複製場景下行為不同(5.6+ 可通過 sysdate-is-now 統一)。

七、Unix 時間戳轉換

函數功能示例
UNIX_TIMESTAMP()當前/指定日期轉秒數(從 1970-01-01 UTC)UNIX_TIMESTAMP('1997-10-04 22:23:00') → 875996580
FROM_UNIXTIME(ts[,fmt])秒數轉日期字符串,可帶格式FROM_UNIXTIME(875996580, '%Y %D %M %h:%i:%s %x') → '1997 23rd December 03:43:30 x'

對 TIMESTAMP 列調用 UNIX_TIMESTAMP 直接讀取內部存儲值,無隱式轉換開銷。

八、秒與時間互轉

SELECT SEC_TO_TIME(2378);      -- '00:39:38'
SELECT TIME_TO_SEC('22:23:00'); -- 80580

九、性能與最佳實踐建議

  1. 索引友好查詢:避免在 WHERE 條件中對列使用函數(如 WHERE DATE(create_time) = '2023-01-01'),改用範圍查詢 WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02' 利用索引。
  2. 時區一致性:應用層、MySQL 會話(SET time_zone)、系統層三者時區保持一致,避免 NOW()/UNIX_TIMESTAMP 跨時區偏差。
  3. 優先使用 DATETIME/TIMESTAMP:而非分離的 DATE+TIME 列,便於範圍查詢與排序。
  4. DATE_FORMAT 在大數據量報表中開銷較大,可考慮應用層格式化或物化視圖預計算。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved