本文目录列表:
 
SQL Server旬时间粒度
 
    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开始计数,12、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、23、……、28293031
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
View Code

    

    提供获得指定日期在当前旬第几天的功能函数,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
View Code

    

    提供旬基准日期和整数相互转换的功能函数,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
View Code

 

相关文章:

  • 2022-12-23
  • 2021-06-03
  • 2022-12-23
  • 2022-01-22
  • 2022-12-23
  • 2022-12-23
  • 2021-12-03
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案