首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 日期函數實戰速查:獲取、格式化、截取、運算、比較、轉換六大場景全覆蓋

     編輯:MySQL 綜合教學

MySQL 日期函數實戰速查:獲取、格式化、截取、運算、比較、轉換六大場景全覆蓋

日期處理是業務開發高頻痛點。本文按場景分類梳理 MySQL 核心日期函數:NOW() vs SYSDATE() 行為差異、DATE_FORMAT 萬能格式化、截取函數族、DATE_ADD 通用運算、DATEDIFF/TIMEDIFF 比較、TO_DAYS/UNIX_TIMESTAMP 轉換,並給出生產環境常見避坑指南與組合招範例。

一、獲取當前日期時間:NOW() vs SYSDATE()

SELECT NOW(), SLEEP(3), NOW();      -- 2015-10-28 22:43:34 | 0 | 2015-10-28 22:43:34 (固定)
SELECT SYSDATE(), SLEEP(3), SYSDATE(); -- 2015-10-28 22:46:48 | 0 | 2015-10-28 22:46:52 (實時)

差異本質**:NOW() 在語句開始執行時確定,存儲函數/觸發器/複製場景下行為確定;SYSDATE() 每次調用取實時值。**生產建議統一使用 NOW()**,除非極少數需要實時時間戳的審計場景。

二、日期格式化:DATE_FORMAT 通配符速查表

SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');           -- 2015-10-28
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');  -- 2015-10-28 22:10:56
SELECT DATE_FORMAT(NOW(), '%W, %M %D, %Y');      -- Wednesday, October 28th, 2015
符號含義示例
%Y4 位年份2015
%y2 位年份15
%m月份 01-1210
%c月份 1-1210
%d日期 01-3128
%e日期 1-3128
%H小時 00-2322
%k小時 0-2322
%h/%I小時 01-1210
%i分鐘 00-5910
%s/%S秒 00-5956
%W星期全名Wednesday
%a星期縮寫Wed
%M月份全名October
%b月份縮寫Oct
%r12 小時制時間10:10:56 PM
%T24 小時制時間22:10:56

避坑**:DATE_FORMAT 返回字符串,不可直接與 DATE/DATETIME 列比較。錯誤:WHERE create_date >= DATE_FORMAT(NOW(), '%Y-%m-%d')。正確:WHERE create_date >= DATE(NOW()) 或 WHERE create_date >= CURDATE()。

三、日期截取:單一分量提取族

SELECT DAYOFWEEK(NOW());        -- 1=週日...7=週六
SELECT DAYOFMONTH('2015-10-28'); -- 28
SELECT DAYOFYEAR('2015-10-28');  -- 301
SELECT YEAR('2015-10-28');       -- 2015
SELECT QUARTER('2015-10-28');    -- 4
SELECT MONTH('2015-10-28');      -- 10
SELECT WEEK('2015-10-28');       -- 43 (預設週日為週首)
SELECT WEEK('2015-10-28', 1);    -- 44 (週一為週首)
SELECT HOUR('2015-10-28 23:11:56');   -- 23
SELECT MINUTE('2015-10-28 23:11:56'); -- 11
SELECT SECOND('2015-10-28 23:11:56'); -- 56
SELECT DATE('2015-10-28 23:11:56');   -- 2015-10-28
SELECT TIME('2015-10-28 23:11:56');   -- 23:11:56

四、日期運算:DATE_ADD 通用加減法

SELECT DATE_ADD('2015-10-28 23:11:56', INTERVAL 4 DAY);        -- 2015-11-01 23:11:56
SELECT DATE_ADD('2015-10-28 23:11:56', INTERVAL -3 DAY);       -- 2015-10-25 23:11:56
SELECT DATE_ADD('2015-10-28 23:11:56', INTERVAL 1 YEAR);       -- 2016-10-28 23:11:56
SELECT DATE_ADD('2015-10-28 23:11:56', INTERVAL '1 3' DAY_HOUR); -- 2015-10-27 20:11:56
SELECT DATE_ADD('2015-10-28 23:11:56', INTERVAL '-1 1:1:1' DAY_SECOND); -- 2015-10-27 22:10:55
單位關鍵字含義表達式格式
SECOND/MINUTE/HOUR/DAY/MONTH/YEAR單一單位數字
MINUTE_SECOND分:秒'MIN:SEC'
HOUR_MINUTE時:分'HOUR:MIN'
DAY_HOUR天 時'DAY HOUR'
YEAR_MONTH年-月'YEAR-MONTH'
HOUR_SECOND時:分:秒'HOUR:MIN:SEC'
DAY_MINUTE天 時:分'DAY HOUR:MIN'
DAY_SECOND天 時:分:秒'DAY HOUR:MIN:SEC'

規則**:正數加、負數減;缺少高位單位時從右補齊(如 DAY_SECOND 缺時分視為 MINUTE_SECOND);月份天數溢出自動截斷到月末。

五、日期比較:差值計算

SELECT DATEDIFF('2015-10-28', '2015-10-26');        -- 2 (天數差)
SELECT TIMEDIFF('2015-10-28 23:11:56', '2015-10-28 20:11:56'); -- 03:00:00 (時分秒差)

六、日期轉換:天數、秒數、時間互轉

SELECT TO_DAYS('2015-10-28 23:11:56');      -- 736264 (西元 0 年至今天數)
SELECT TO_DAYS('0000-00-00 00:00:00');      -- 0
SELECT UNIX_TIMESTAMP('2015-10-28 23:11:56'); -- 1446045116 (1970-01-01 UTC 起秒數)
SELECT TIME_TO_SEC('01:00:05');              -- 3605
SELECT SEC_TO_TIME(3605);                    -- 01:00:05

七、實戰組合招:本月首尾、本週首尾、去同期

-- 本月第一天 00:00:00
SET @month_start = DATE(DATE_FORMAT(NOW(), '%Y-%m-01'));
-- 本月最後一天 23:59:59
SET @month_end = DATE_SUB(DATE_ADD(@month_start, INTERVAL 1 MONTH), INTERVAL 1 SECOND);

-- 本週一 00:00:00 (模式 1: 週一為週首)
SET @week_start = DATE_SUB(NOW(), INTERVAL WEEKDAY(NOW()) DAY);
SET @week_start = DATE(@week_start);
-- 本週日 23:59:59
SET @week_end = DATE_ADD(@week_start, INTERVAL 6 DAY);
SET @week_end = DATE_SUB(@week_end, INTERVAL -1 SECOND);

-- 去年同期對比
SELECT * FROM sales
WHERE sale_date BETWEEN DATE_SUB(@month_start, INTERVAL 1 YEAR) AND DATE_SUB(@month_end, INTERVAL 1 YEAR);

將此速查表釘在工位,下次寫日期邏輯直接複製粘貼修改參數,告別「這個函數怎麼用」的現場查文檔。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved