SQL Server 2005 僅提供 datetime 與 smalldatetime 兩種日期時間類型(無獨立日期/時間類型)。本文詳解儲存結構、精度、日期範圍查詢陷阱、六大字串輸入格式、CONVERT 輸出控制、核心日期函數,並匯總截尾、足年足月等高頻實用查詢模式。
1900-01-01 之前/之後的天數(負/正),範圍 1753-01-01 ~ 9999-12-31。1900-01-01 後的天數,範圍 1900-01-01 ~ 2079-06-06。因 datetime 精度 3.33 ms,23:59:59.999 會進位為隔天 00:00:00.000。
-- 錯誤:會包含隔天 00:00:00.000
WHERE Date >= '1998-01-01 00:00:00.000' AND Date <= '1998-01-01 23:59:59.999'
-- 正確:半開區間
WHERE Date >= '1998-01-01 00:00:00.000' AND Date < '1998-01-02 00:00:00.000'
| 格式類型 | 範例 | 特點 |
|---|---|---|
| ISO 8601 | yyyy-mm-ddThh:mi:ss.mmm | 國際標準,不受 SET DATEFORMAT/LANGUAGE 影響,強烈推薦 |
| 字母日期 | Apr 15, 1996 / 15 Apr 1996 | 僅支援月份名稱為字母的語言(中文/日文/韓文不支援) |
| ODBC 時間戳記 | { ts '1998-05-02 01:23:56.123' } | ADO/OLE DB/ODBC 應用程式常用,{ d '...' } { t '...' } 亦可 |
| 分隔字串 | 04/15/1996 15-04-1996 1996.04.15 | 受 SET DATEFORMAT (mdy/dmy/ymd...) 影響,跨語言易混淆 |
| 未分隔字串 | 19960415 (8碼) 960415 (6碼) | 永遠解釋為 ymd,不受 DATEFORMAT 影響 |
| 時間部分 | 14:30 4 PM 14:30:20.500 | 無日期時預設 1900-01-01;支援 AM/PM、12/24 小時制 |
殺手鐧:CONVERT(datetime, 'string', style) 顯式指定樣式碼,完全繞過語言/格式設定干擾。
僅能透過 CONVERT(varchar, date_col, style) 格式化輸出。樣式碼與輸入相同(如 120 = yyyy-mm-dd hh:mi:ss,112 = yyyymmdd)。
DATEADD(datepart, number, date):加減運算,構造「下個月今天」、「月底」等,自動處理閏年/月末邊界。DATEDIFF(datepart, start, end):差值計算,忽略比指定精度更高的單位(如算月差不看日)。DATEPART(datepart, date) / DATENAME(datepart, date):取部分值(數值/字串)。GETDATE() / CURRENT_TIMESTAMP:本機當前時間。GETUTCDATE():UTC 時間。常用 datepart 縮寫:year/yy/yyyy、quarter/qq/q、month/mm/m、day/dd/d、week/wk/ww、hour/hh、minute/mi/n、second/ss/s、millisecond/ms。
-- 本月/年/週/季 初
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0); -- 月初
SELECT DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0); -- 年初
SELECT DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0); -- 本週一
SELECT DATEADD(QUARTER,DATEDIFF(QUARTER,0, GETDATE()), 0); -- 季初
-- 本月/年/週/季 末 (下一個起始點 - 1ms/1天)
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0) - 1; -- 月末
SELECT DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0) - 1; -- 年末
-- 足年計算 (三種寫法,閏年處理不同)
-- 法一:用 DATEADD 還原周年日比較 (閏年 2/29 = 平年 2/28)
-- 法二:MONTH*100 + DAY 比較 (閏年 2/29 = 平年 3/1)
-- 法三:DAYOFYEAR 比較 (閏年後日期相差 1 天)
-- 足月計算
-- 法一:DATEADD 還原月週年日比較
-- 法二:DAY() 直接比較日部分