核心函數速查表
| 函數 | 語法 | 說明 | 常用 datepart |
| GETDATE() | GETDATE() | 回傳目前系統日期時間(精度 ~3.33ms) | - |
| SYSDATETIME() | SYSDATETIME() | 高精度(100ns)目前日期時間,建議新專案使用 | - |
| DATEADD | DATEADD(datepart, number, date) | 在日期加減指定間隔,回傳新 datetime | year/yy, quarter/qq, month/mm, day/dd, week/wk, hour/hh, minute/mi, second/ss, millisecond/ms |
| DATEDIFF | DATEDIFF(datepart, start, end) | 回傳兩日期間的 datepart 邊界數(整數) | 同上 |
| DATEPART | DATEPART(datepart, date) | 回傳指定部分的整數值 | 同上 |
| DATENAME | DATENAME(datepart, date) | 回傳指定部分的字串(如月份名稱) | 同上 |
| ISDATE | ISDATE(expression) | 驗證運算式是否為有效日期(1/0) | - |
| CONVERT | CONVERT(target_type, expr, style) | 日期↔字串格式化,style 代碼控制輸出格式 | 見下表 |
| FORMAT | FORMAT(value, format [, culture]) | .NET 格式化字串(SQL 2012+),功能最強但效能較慢 | - |
CONVERT 風格代碼常用對照(日期部份)
| Style | 輸出範例 | 說明 |
| 112 | 20241231 | YYYYMMDD(檔名、排序友善) |
| 120 | 2024-12-31 23:59:59 | ODBC 標準 YYYY-MM-DD HH:MI:SS(24h) |
| 121 | 2024-12-31 23:59:59.123 | 含毫秒的 ODBC 標準 |
| 10 | 12-31-2024 | MM-DD-YYYY |
| 111 | 2024/12/31 | YYYY/MM/DD |
| 106 | 31 Dec 2024 | DD Mon YYYY |
實用範例集
-- 1. 當前時間 ± N 天/月/年
SELECT DATEADD(DAY, 5, GETDATE()); -- 5 天后
SELECT DATEADD(MONTH, -3, GETDATE()); -- 3 月前
-- 2. 兩日期相差天數/月數
SELECT DATEDIFF(DAY, '2024-01-01', GETDATE());
SELECT DATEDIFF(MONTH, HireDate, GETDATE()) FROM Employees;
-- 3. 當月第一天 / 最後一天
SELECT DATEADD(DAY, 1-DAY(GETDATE()), CAST(GETDATE() AS DATE)); -- 月初
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())+1, 0)); -- 月末
-- 4. 日期截取到日/時/分(去除時間部份)
SELECT CAST(GETDATE() AS DATE); -- 僅日期 (SQL 2008+)
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0); -- 相容舊版:午夜 00:00:00
-- 5. 字串轉日期(安全解析)
SELECT TRY_CONVERT(DATETIME, '2024-12-31', 120); -- 失敗回 NULL (SQL 2012+)
SELECT CASE WHEN ISDATE('2024-13-01')=1 THEN CONVERT(DATETIME, '2024-13-01') END;
-- 6. 取得年/月/日/週/季
SELECT DATEPART(YEAR, GETDATE()), DATENAME(MONTH, GETDATE()),
DATEPART(WEEK, GETDATE()), DATEPART(QUARTER, GETDATE());
-- 7. 週一作為週起始(ISO 8601)
SELECT DATEPART(ISO_WEEK, GETDATE()); -- SQL 2008+
效能與最佳實務
- 避免在 WHERE 對欄位用函數:
WHERE DATEDIFF(DAY, CreateTime, GETDATE()) = 0 → 導致索引掃描。改用範圍查詢:WHERE CreateTime >= CAST(GETDATE() AS DATE) AND CreateTime < DATEADD(DAY, 1, CAST(GETDATE() AS DATE))。
- 儲存用 UTC:資料庫儲存
DATETIMEOFFSET 或 UTC DATETIME2,顯示層再轉時區。
- 精度選擇:
DATETIME2(n) 可指定小數秒精度(0~7),儲存體 6~8 bytes,優於固定 8 bytes 的 DATETIME(精度 3.33ms)。