SQL Server日期函数实战:格式化、运算与时区处理详解
在处理SQL Server数据时,日期时间的格式化、计算与时区转换是高频需求。文章通过对比传统CONVERT与新式FORMAT函数,梳理了EOMonth、DatePart等常用函数的参数与返回值,并结合实际场景提供获取首尾日期、跨时区时间及范围查询的完整代码方案。
一、日期与字符串的相互转换
在SQL Server中,将日期类型(Date/DateTime)转换为字符类型通常涉及两种主流方式:传统的CONVERT()和更灵活的FORMAT()。
第1步:使用传统 CONVERT 函数控制样式
目的:利用系统预定义的整数样式码(style)快速输出标准格式。
- 语法:
CONVERT ( data_type [ ( length ) ], expression [, style ] ) - 特点:性能较好,但style代码繁多且难以记忆,灵活性受限。
- 常用Style对照:
101: mm/dd/yyyy (美式)110: mm-dd-yyyy111: yyyy/mm/dd (日式)112: yyyymmdd (无分隔符ISO标准)120: yyyy-mm-dd hh:mm:ss121: yyyy-mm-dd hh:mm:ss.ffffff
第2步:使用 FORMAT 函数自定义格式
目的:借助.NET Framework格式化规则,对日期或数值进行更直观的定制,并支持多语言文化。
- 语法:
FORMAT ( value, format [, culture ] ) - 返回值:NVARCHAR。若格式转换失败则返回NULL。
- 占位符说明:
yyyy, MM, dd:年、月、日hh, mm, ss:时、分、秒- 连接符如“-”或“/”可自由替换以适配不同显示需求。
操作示例:输出精确到微秒的标准时间格式。
SELECT FORMAT(SYSDATETIME(), 'yyyy-MM-dd HH:mm:ss.fffffff');
此外,FORMAT()同样适用于数值格式化,例如使用#作为数字占位符:
SELECT FORMAT(123456789, '###-##-####') AS 'Custom Number Result'
二、日期信息的提取与重构
第3步:提取日期组成部分
目的:从完整的日期时间对象中拆解出年、月、日、周、季等维度信息。
- 数值型提取:推荐使用
DATENAME()返回字符串,或用DATEPART()/YEAR()/MONTH()返回整数。
关键参数(datepart):quarter: 季度(1-4)week: 年第几周dayofyear: 年第几天weekday: 星期几(受SET DATEFIRST影响)
- 日期重构:基于离散的数字组件重新组装为日期对象,避免拼接字符串带来的类型错误。
-- 组合年月日为日期对象
SELECT DATEFROMPARTS(year(@date), month(@date), day);
-- 带时分秒的高精度重组
SELECT DATETIME2FROMPARTS(year, month, day, hour, minute, seconds, fractions, precision);
三、常见业务场景下的日期运算
第4步:快速获取月份的首尾日期
目标:解决报表统计中常见的“本月起止”、“上月末”问题。
- 获取当月最后一天:使用
EOMONTH(),比传统嵌套计算更直观。 - 获取当月第一天:可将日的部分设为1。
-- EOMONTH(start_date[, month_to_add])
DECLARE @currentDate DATE = GETDATE();
SELECT
EOMONTH(@currentDate) AS CurrentMonthEnd,
EOMONTH(@currentDate, -1) AS PreviousMonthEnd;
-- 获取当月第一天
SELECT DATEFROMPARTS(YEAR(@currentDate), MONTH(@currentDate), 1);
-- 或使用格式转换法获取字符型首日
SELECT FORMAT(GETDATE(), 'yyyyMM01');
第5步:处理不同时区数据
目标:将datetimeoffset类型的数据转换为目标时区。
- 方法:使用
SWITCHOFFSET()。该函数保留绝对时间点不变,仅改变偏移量表示。 - 注意:
time_zone参数格式为[+|-] hh:mm。
DECLARE @remote DATETIMEOFFSET;
DECLARE @local DATETIMEOFFSET = SYSDATETIMEOFFSET();
-- 将当前本地时间切换到东七区 (+07:00)
SET @remote = SWITCHOFFSET(@local, '+07:00');
SELECT @remote AS RemoteTime, @local AS LocalTime;
第6步:确定当前日期是周几
目标:获取星期的名称或数字索引。
- 名称获取:
DATENAME(WEEKDAY, ...)的结果依赖于服务器配置的默认语言(可通过@@LANGUAGE查看或设置)。 - 索引获取:
DATEPART(WEEKDAY, ...)返回1-7。其具体映射关系(周几是1还是7)取决于SET DATEFIRST的设置(默认为美国英语标准的7=Sunday)。
-- 查看当前语言设置
SELECT @@LANGUAGE;
-- 获取中文显示的星期名
SET LANGUAGE 'Simplified Chinese';
SELECT DATENAME(WEEKDAY, GETUTCDATE());
四、综合查询与参考速查
除了上述独立函数,DATEADD和DATEDIFF是构建复杂查询条件的基础。
经典日期函数表
DATEADD(part, number, date):在指定日期基础上增加/减少时间间隔。常用于推算未来/过去时间。DATEDIFF(part, start, end):计算两个日期之间特定部分的时间差值(整数)。GETDATE()/GETUTCDATE():分别获取当前系统时间和UTC标准时间。
基于 DATEDIFF 的常见过滤逻辑
假设字段名为CreateDate,以下为几种典型的数据查询写法:
- 今日数据:
WHERE DATEDIFF(DAY, CreateDate, GETDATE()) = 0 - 昨日数据:
WHERE DATEDIFF(DAY, CreateDate, GETDATE()) = 1 - 前N天数据:
WHERE DATEDIFF(DAY, CreateDate, GETDATE()) <= N - 本周数据:
WHERE DATEDIFF(WEEK, CreateDate, GETDATE()) = 0 - 本月数据:
WHERE DATEDIFF(MONTH, CreateDate, GETDATE()) = 0
以上就是关于SQL Server日期函数及其在实际开发中应用的详细内容,更多关于SQL Server数据库操作的技巧资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









