在 SQL Server 中处理日期格式,几乎是每个数据库开发者都会碰到的场景。无论是做报表展示、生成分表名,还是进行日期筛选,格式的转换和控制都绕不过去。这篇我们就把这件事彻底讲透——从基础函数到实战技巧,从预定义格式到自定义方案,覆盖日常开发中所有常见的日期显示需求。

一、核心函数:CONVERT(兼容所有版本,推荐)
先说 CONVERT——这是 SQL Server 里最基础、兼容性最好的日期转换利器。无论你用的是 SQL Server 2008 还是 2022,它都稳如磐石。语法很简单:
CONVERT(目标类型, 日期值, 格式代码)
目标类型一般设为 VARCHAR 或 NVARCHAR(长度按需指定)。格式代码是 SQL Server 预定义的数字编码,不同数字对应不同格式。
1. 最常用的预定义格式(必记)
下面这几组代码,在日常开发中间出镜率最高,值得记忆:
DECLARE @Date DATETIME = GETDATE(); -- 1. 仅日期(YYYY-MM-DD):格式代码 23 SELECT CONVERT(VARCHAR(10), @Date, 23) AS 日期_YYYYMMDD; -- 输出:2026-02-27 -- 2. 仅时间(HH:MI:SS):格式代码 8 SELECT CONVERT(VARCHAR(8), @Date, 8) AS 时间_HHMMSS; -- 输出:15:30:45 -- 3. 日期+时间(YYYY-MM-DD HH:MI:SS):格式代码 120 SELECT CONVERT(VARCHAR(19), @Date, 120) AS 日期时间_完整; -- 输出:2026-02-27 15:30:45 -- 4. 纯数字日期(YYYYMMDD):格式代码 112 SELECT CONVERT(VARCHAR(8), @Date, 112) AS 日期_纯数字; -- 输出:20260227(适配你的分表名) -- 5. 中文格式(YYYY年MM月DD日):格式代码 111 + 替换符号 SELECT REPLACE(REPLACE(CONVERT(VARCHAR(10), @Date, 111), '/', '年'), '/', '月') + '日' AS 日期_中文; -- 输出:2026年02月27日 -- 6. 带毫秒的时间(HH:MI:SS.MMM):格式代码 121 SELECT CONVERT(VARCHAR(23), @Date, 121) AS 日期时间_带毫秒; -- 输出:2026-02-27 15:30:45.123
2. 常用格式代码速查表
为了方便查阅,这里整理了一份速查表:
| 格式代码 | 格式示例 | 适用场景 |
|---|---|---|
| 8 | 15:30:45 | 仅显示时间 |
| 10 | 02-27-26 | 美式短日期(MM-DD-YY) |
| 23 | 2026-02-27 | 标准日期(推荐) |
| 101 | 02/27/2026 | 美式日期(MM/DD/YYYY) |
| 112 | 20260227 | 纯数字日期(分表名 / 文件名) |
| 120 | 2026-02-27 15:30:45 | 标准日期时间(推荐) |
| 121 | 2026-02-27 15:30:45.123 | 带毫秒的日期时间 |
二、灵活自定义:FORMAT 函数(SQL Server 2012+)
如果觉得 CONVERT 的预定义格式不够灵活,那 FORMAT 就是答案。它支持自定义格式字符串(和 C#/.NET 的日期格式完全一致),你甚至可以指定区域设置(比如输出中文星期)。语法:
FORMAT(日期值, '自定义格式', '区域设置')
1. 常用自定义格式示例
DECLARE @Date DATETIME = GETDATE(); -- 1. 自定义日期(YYYY年MM月DD日 HH时MI分SS秒) SELECT FORMAT(@Date, 'yyyy年MM月dd日 HH时mm分ss秒') AS 日期_中文完整; -- 输出:2026年02月27日 15时30分45秒 -- 2. 短日期(YY-MM-DD) SELECT FORMAT(@Date, 'yy-MM-dd') AS 日期_短格式; -- 输出:26-02-27 -- 3. 星期几 SELECT FORMAT(@Date, 'dddd') AS 星期_英文; -- 输出:Friday SELECT FORMAT(@Date, 'dddd', 'zh-CN') AS 星期_中文; -- 输出:星期五 -- 4. 月份名称 SELECT FORMAT(@Date, 'MMMM', 'zh-CN') AS 月份_中文; -- 输出:二月 -- 5. 24小时制/12小时制 SELECT FORMAT(@Date, 'hh:mm:ss tt') AS 时间_12小时制; -- 输出:03:30:45 下午 SELECT FORMAT(@Date, 'HH:mm:ss') AS 时间_24小时制; -- 输出:15:30:45
2. 自定义格式符速查表
格式符的具体含义也列出来,方便组合使用:
| 格式符 | 说明 | 示例 |
|---|---|---|
| yyyy | 4 位年 | 2026 |
| yy | 2 位年 | 26 |
| MM | 2 位月(补 0) | 02 |
| M | 1 位月(不补 0) | 2 |
| dd | 2 位日(补 0) | 27 |
| d | 1 位日(不补 0) | 27 |
| HH | 24 小时制(补 0) | 15 |
| hh | 12 小时制(补 0) | 03 |
| mm | 分钟(补 0) | 30 |
| ss | 秒(补 0) | 45 |
| fff | 毫秒 | 123 |
| tt | 上午 / 下午(12 小时制) | 下午 |
三、全局格式设置(影响会话 / 服务器)
如果你希望整个会话甚至服务器的日期显示格式统一,可以修改 DATEFORMAT 或服务器配置。但说实话,这种“一刀切”的做法在实际项目中用得不多——更多时候我们还是用 CONVERT 或 FORMAT 做局部控制。
1. 会话级设置(仅当前连接有效)
-- 设置日期解析/显示的顺序:年-月-日(dmy=日-月-年,mdy=月-日-年) SET DATEFORMAT ymd; -- 设置语言(影响日期的中文/英文显示) SET LANGUAGE Chinese; -- 中文 -- SET LANGUAGE English; -- 英文 -- 验证:默认显示格式会随语言变化 SELECT GETDATE() AS 默认日期格式;
2. 服务器级设置(需管理员权限)
通过 SSMS 修改:右键服务器 →「属性」→「高级」→ 找到「默认语言」「日期格式」,修改后重启 SQL Server 服务。
需要提醒的是,服务器级别的格式修改可能会影响到其他业务系统的表现,实际建议优先使用 CONVERT/FORMAT 做局部转换,谁用谁知道。
四、实战场景示例
理论说完了,来看看几个真实场景下的用法。
场景 1:生成分表名(如 DefectResult2026021)
-- 获取当前年月的纯数字格式,拼接到分表名 DECLARE @TableName NVARCHAR(100); SET @TableName = N'DefectResult' + CONVERT(VARCHAR(6), GETDATE(), 112) + N'1'; SELECT @TableName AS 分表名; -- 输出:DefectResult2026021
场景 2:查询结果显示中文日期
-- 查询订单表,显示中文格式的下单时间
SELECT
OrderID,
FORMAT(CreateTime, 'yyyy年MM月dd日 HH:mm:ss', 'zh-CN') AS 下单时间,
FORMAT(CreateTime, 'dddd', 'zh-CN') AS 下单星期
FROM Orders;
场景 3:按指定格式筛选日期
-- 筛选2026年2月的订单(用112格式避免格式冲突) SELECT * FROM Orders WHERE CONVERT(VARCHAR(6), CreateTime, 112) = '202602';
五、避坑点
最后聊几个容易翻车的点:
- 避免直接比较字符串日期:❌ 错误:
WHERE CONVERT(VARCHAR(10), CreateTime, 23) = '2026-02-27';✅ 正确:WHERE CreateTime >= '2026-02-27' AND CreateTime < '2026-02-28'——直接比较日期类型,利用索引才是正道。 - FORMAT 函数的性能问题:
FORMAT虽然灵活,但性能比CONVERT差不少。如果是百万级以上的数据量,优先用CONVERT。 - NULL 日期处理:转换前最好用
ISNULL处理 NULL,不然结果直接飘 NULL:
SELECT ISNULL(CONVERT(VARCHAR(10), CreateTime, 23), '未填写') AS 日期 FROM Users;
总结
梳理一下核心要点:
- 兼容性优先:用
CONVERT(字段, 格式代码)(如 23=YYYY-MM-DD、112=YYYYMMDD),适配所有 SQL Server 版本; - 灵活性优先:SQL Server 2012+ 用
FORMAT(字段, '自定义格式', 'zh-CN'),支持中文 / 自定义格式; - 核心场景:
- 分表名 / 文件名:用
CONVERT(..., 112)生成纯数字日期; - 前端展示:用
FORMAT生成中文 / 自定义格式; - 日期筛选:直接比较日期类型,避免转换为字符串;
- 分表名 / 文件名:用
- 避坑:避免全局修改日期格式,优先局部转换;大数据量场景慎用
FORMAT。
没有银弹,看场景选最实用的就行。希望这篇文章能帮你搞定 SQL Server 日期格式的日常甩锅。
