本文目录列表:
SQL Server不存在旬这个时间粒度,这个时间粒度在我们国家存在的。一个月分为上、中、下3旬,上旬和中旬均10天,分别对应第1天到第10天和第11天到第20天,下旬有可能8天、9天、10天和11天,从第21天到月末最后1天。从旬的定义得知旬是个日期时间范围的,那么如何实现将旬时间粒度时间值和一个对应的整数来实现相互转换呢?从旬的定义得知每旬都有个开始日期的,这个日期我们就叫做旬基准日期。如果同一旬的任意一个日期都对应一个相同的整数,那么再将一个整数转换为一个旬基准日期,这样我们可以实现旬基准日期和整数的相互转换。我们还可以得到每个日期在所在旬的第几天,也可以将得到一个月份每日期所在的旬索引(这个类似每周的任何一天对应的weekday值,从1到7分别对应星期一到星期日)。
提供获得指定日期在当前月哪个旬的功能的函数,T-SQL代码如下:
1 IF OBJECT_ID(N'dbo.ufn_PeriodOfMonth', 'FN') IS NOT NULL 2 BEGIN 3 DROP FUNCTION dbo.ufn_PeriodOfMonth; 4 END 5 GO 6 7 --================================== 8 -- 功能: 获得指定日期时间在当前月的旬索引 9 -- 说明: 从1开始计数,1、2、3分别对应上、中、下的旬索引。 10 -- 作者: XXX 11 -- 创建: yyyy-MM-dd 12 -- 修改: yyyy-MM-dd XXX 修改内容描述 13 -- 调用: SET @intPeriods = dbo.ufn_PeriodOfMonth('2008-01-14') 14 --================================== 15 CREATE FUNCTION [dbo].[ufn_PeriodOfMonth] 16 ( 17 @dtmDate DATETIME -- 指定的日期时间 18 ) RETURNS TINYINT 19 --$Encode$-- 20 AS 21 BEGIN 22 --当前月的日索引,从1开始计数,,包括1、2、3、……、28、29、30、31 23 DECLARE @tintDayOfMonth AS TINYINT; 24 SET @tintDayOfMonth = DAY(@dtmDate); 25 -- 旬偏移索引,0:上旬,1:中旬,2:下旬 26 DECLARE @tintPeriodOffsetIndexID AS INT; 27 SET @tintPeriodOffsetIndexID = DAY(@dtmDate) / 10 28 29 IF @tintDayOfMonth IN (10, 20, 30, 31) 30 BEGIN 31 SET @tintPeriodOffsetIndexID = @tintPeriodOffsetIndexID - 1; 32 END 33 34 RETURN @tintPeriodOffsetIndexID + 1; 35 END 36 GO
提供获得指定日期在当前旬第几天的功能函数,T-SQL代码如下:
1 IF OBJECT_ID(N'dbo.ufn_DayOfPeriod', 'FN') IS NOT NULL 2 BEGIN 3 DROP FUNCTION dbo.ufn_DayOfPeriod; 4 END 5 GO 6 7 --================================== 8 -- 功能: 获得指定日期时间在当前旬的日索引 9 -- 说明: 从1开始计数,包括1、2、3、……、8、9、10、11 10 -- 作者: XXX 11 -- 创建: yyyy-MM-dd 12 -- 修改: yyyy-MM-dd XXX 修改内容描述 13 -- 调用: SET @intPeriods = dbo.ufn_DayOfPeriod('2008-01-14') 14 --================================== 15 CREATE FUNCTION [dbo].[ufn_DayOfPeriod] 16 ( 17 @dtmDate DATETIME -- 指定的日期时间 18 ) RETURNS TINYINT 19 --$Encode$-- 20 AS 21 BEGIN 22 RETURN DAY(@dtmDate) - (dbo.ufn_PeriodOfMonth(@dtmDate) - 1) * 10; 23 END 24 GO
提供旬基准日期和整数相互转换的功能函数,T-SQL代码如下:
1 IF OBJECT_ID(N'dbo.ufn_Periods', 'FN') IS NOT NULL 2 BEGIN 3 DROP FUNCTION dbo.ufn_Periods; 4 END 5 GO 6 7 --================================== 8 -- 功能: 获得指定日期时间基于基准日期的总旬数(一个整数值) 9 -- 说明: 如果指定的日期时间为NULL或者小于基准日期“1900-01-01”时,则其值默认基准日期; 10 -- 结果值为非负整数,从0开始计数。 11 -- 作者: XXX 12 -- 创建: yyyy-MM-dd 13 -- 修改: yyyy-MM-dd XXX 修改内容描述 14 -- 调用: SET @intPeriods = dbo.ufn_Periods('2008-01-14') 15 --================================== 16 CREATE FUNCTION [dbo].[ufn_Periods] 17 ( 18 @dtmDate DATETIME -- 指定的日期时间 19 ) RETURNS INT 20 --$Encode$-- 21 AS 22 BEGIN 23 SET @dtmDate = dbo.ufn_GetValidDate(@dtmDate); 24 25 -- 旬偏移索引ID,0:上旬,1:中旬,2:下旬 26 DECLARE @tintPeriodOffsetIndexID AS INT; 27 SET @tintPeriodOffsetIndexID = dbo.ufn_PeriodOfMonth(@dtmDate); 28 29 -- datepart参数也可以为mm或m 30 RETURN DATEDIFF(MONTH, '1900-01-01', @dtmDate) * 3 + @tintPeriodOffsetIndexID; 31 END 32 GO 33 34 IF OBJECT_ID(N'dbo.ufn_Periods2Date', 'FN') IS NOT NULL 35 BEGIN 36 DROP FUNCTION dbo.ufn_Periods2Date; 37 END 38 GO 39 40 --================================== 41 -- 功能: 获得一个整数值基于基准日期对应的旬基准日期 42 -- 说明: 如果指定的整数值为NULL或为负整数时,则其值默认为0; 43 -- 如果指定的整数值大于“9999-12-31”对应的整数值时,则其值默认设置为“9999-12-31”对应的整数值; 44 -- 结果值为从基准日期开始计数的日期; 45 -- 旬基准日期是指一个月份中第1天、第11天和第21天对应的日期,比如'2016-02'月份的3个旬基准日期分别为'2016-02-01','2016-02-11','2016-02-21'。 46 -- 作者: XXX 47 -- 创建: yyyy-MM-dd 48 -- 修改: yyyy-MM-dd XXX 修改内容描述 49 -- 调用: SET @dtmDate = dbo.ufn_Periods2Date(2705) --'1975-02-21' 50 --================================== 51 Create FUNCTION dbo.ufn_Periods2Date 52 ( 53 @intPeriods INT 54 ) RETURNS DATETIME 55 AS 56 BEGIN 57 SET @intPeriods = dbo.ufn_GetValidDateNum(@intPeriods); 58 59 DECLARE @intMaxPeriods AS INT; 60 SET @intMaxPeriods = dbo.ufn_Periods('9999-12-31'); 61 62 IF @intPeriods >= @intMaxPeriods 63 BEGIN 64 SET @intPeriods = @intMaxPeriods; 65 END 66 67 -- datepart参数也可以为mm或m 68 -- 以下注释的也可以,不过更接近相对日期+偏移数得到旬基准日期。 69 --RETURN DATEADD(MONTH, @intPeriods / 3, '1900-01-01') + (@intPeriods - @intPeriods / 3 * 3) * 10; 70 RETURN DATEADD(DAY, (@intPeriods - @intPeriods / 3 * 3) * 10, DATEADD(MONTH, @intPeriods / 3, '1900-01-01')); 71 END 72 GO