将该系列涉及到的时间粒度以及分钟以下的粒度做个总结,如以下表格:

时间粒度
 
 
   
 
 
 
 
纳秒
 
 
 
 
 
 
 
 
微妙
 
 
 
 
 
 
 
 
毫秒
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
分钟
日期分钟数(整数)*
日期分钟*
日内分钟数
 
 
 
 
 
小时
日期小时数(整数)
日期小时
日内小时数
 
 
 
 
 
日期天数(整数)
日期天
周内日索引
旬内日索引
月内日索引
季内日索引
年内日索引 日期内日索引
日期周数(整数)
日期周
旬内周索引
月内周索引
季内周索引
年内周索引
日期内周索引
 
日期旬数(整数)
日期旬
月内旬索引 季内旬索引
年内旬索引
日期内旬索引
 
 
日期月数(整数)
日期月
季内月索引
年内月索引
日期内月索引
 
 
 
日期季数(整数)
日期季
年内季索引
日期内季索引
 
 
 
 
日期年数(整数)
日期年
日期内年索引
 
 
 
 
 

注意:

1、最左边第一列表示时间粒度,其左边列的空格表示没有相应的参数,有文字表示有相对应的功能函数。
2、带有数的描述从0开始计数,带有索引则是从1开始计数。
3、日期天和日期天数(整数)是一对一映射的,一个日期对应一个整数。日期周、日期旬、日期月、日期季、日期年都是其时间粒度的基准日期的。
4、日期内相关的索引这个日期内是个范围区间[0001-01-01,9999-12-31],时间粒度日、周、旬、月、季、年的有关日期内的相关索引都是基于这个范围区间计算的。
5、带有*符号的表示谨慎使用。
 
时间维度有关功能函数
    
    根据时间粒度有关表述中总结的表格,将提供的时间粒度有关功能函数分为:日期时间通用有关函数、分钟时间粒度有关函数、 小时时间粒度有关函数、周以上时间粒度基准日期有关函数、天时间粒度有关函数、周时间粒度有关函数、旬时间粒度有关函数、月时间粒度有关函数、季时间粒度有关函数、年时间粒度有关函数。日期时间通用函数主要包括获取最小日期时间、获取最大日期时间、获取默认基准日期以及获取有效日期时间和有效日期时间数的函数。周以上时间粒度基准日期就是获取周、旬、月、季、年和日期的相关基准日期,都是其时间刻度的第一天所对应的日期范围。
 
    日期时间通用有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_GetMinDateTime', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_GetMinDateTime
END
GO
 
--==================================
-- 功能: 获取最小日期时间
-- 说明: 运行在SQL Server 2008+。
--       结果值为date数据类型。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_GetMinDateTime();
--==================================
CREATE FUNCTION dbo.ufn_GetMinDateTime
(
 
) RETURNS DATE
    --$Encode$--
AS 
BEGIN
    RETURN '0001-01-01';
END
GO
 
IF OBJECT_ID(N'dbo.ufn_GetMaxDateTime', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_GetMaxDateTime
END
GO
 
--==================================
-- 功能: 获取最最大日期时间
-- 说明: 运行在SQL Server 2005+。
--       结果值为datetime数据类型。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_GetMaxDateTime();
--==================================
CREATE FUNCTION dbo.ufn_GetMaxDateTime
(
 
) RETURNS DATETIME
    --$Encode$--
AS 
BEGIN
    RETURN '9999-12-31 23:59:59';
END
GO
 
IF OBJECT_ID(N'dbo.ufn_GetDefaultBasedate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_GetDefaultBasedate
END
GO
 
--==================================
-- 功能: 获取默认基准日期
-- 说明: 运行在SQL Server 2005+。
--       默认设置为"1900-01-01",调整范围区间为[1753-01-01,9999-12-31];可以调整为该区间任意一个日期,不能为该区间以外的。
--       结果值为datetime数据类型。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_GetDefaultBasedate();
--==================================
CREATE FUNCTION dbo.ufn_GetDefaultBasedate
(
 
) RETURNS DATETIME
    --$Encode$--
AS 
BEGIN
    RETURN '1900-01-01';
END
GO
 
-- Test Code
SELECT dbo.ufn_GetMinDateTime() AS 'MinDateTime'
    ,dbo.ufn_GetMaxDateTime() AS 'MaxDateTime'
    ,dbo.ufn_GetDefaultBasedate() AS 'DefaultBasedate';
GO
 
IF OBJECT_ID(N'dbo.ufn_GetValidDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_GetValidDate;
END
GO
 
--==================================
-- 功能: 获取有效日期
-- 说明: 运行在SQL Server 2005+。
--         指定的日期如果为NULL或者小于默认基准日期时则直接返回默认基准日期。
--       结果值为datetime数据类型。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_GetValidDate('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_GetValidDate
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS DATETIME
    --$Encode$--
BEGIN
    DECLARE @dtmDefaultBasedate AS DATETIME;
    SET @dtmDefaultBasedate = dbo.ufn_GetDefaultBasedate();
 
    IF @dtmDate IS NULL OR @dtmDate < @dtmDefaultBasedate
    BEGIN
        RETURN @dtmDefaultBasedate;
    END
 
    RETURN @dtmDate;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_GetValidDateNum', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION ufn_GetValidDateNum;
END
GO
 
--==================================
-- 功能: 获取有效日期数
-- 说明: 运行在SQL Server 2005+。
--       指定的日期数如果为NULL或负数,则默认设置为0。
--       结果值为datetime数据类型。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @@intDateNum = dbo.ufn_GetValidDateNum(-1)
--==================================
CREATE FUNCTION dbo.ufn_GetValidDateNum
(
    @intDateNum INT            -- 指定的日期数
) RETURNS INT
    --$Encode$--
BEGIN
    IF @intDateNum IS NULL OR @intDateNum < 0
    BEGIN
        RETURN 0;
    END
 
    RETURN @intDateNum;
END
GO
 
-- Test Code
SELECT dbo.ufn_GetValidDate('1899-01-01') AS 'ValidDate'
    ,dbo.ufn_GetValidDateNum(0) AS 'ValidDateNum';
GO
 
以上5个通用函数的测试效果,如下图:
 
    分钟时间粒度有关函数,T-SQL代码如下:
 IF OBJECT_ID(N'dbo.ufn_Minutes', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Minutes;
END
GO
 
--==================================
-- 功能: 获得指定的日期时间基于默认基准日期的总小时数(一个整数值)
-- 说明: 运行在SQL Server 2005 +。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intMinutes = dbo.ufn_Minutes('5983-01-24 02:07:00.000');
--==================================
CREATE FUNCTION dbo.ufn_Minutes
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS INT
AS
BEGIN
    RETURN DATEDIFF(MINUTE, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Minutes2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Minutes2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的日期时间
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0。
--       如果指定的整数值大于“5983-01-24 02:07:00”对应的整数值时,则其值默认设置为“5983-01-24 02:07:00”对应的整数值。
--       结果值为基于默认基准日期开始计数的日期。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Minutes2Date(947033) -- '2008-01-14 17:00'
--==================================
CREATE FUNCTION dbo.ufn_Minutes2Date
(
    @intMinutes INT                -- 指定的整数值
) RETURNS DATETIME
AS
BEGIN
    SET @intMinutes = dbo.ufn_GetValidDateNum(@intMinutes);
 
    DECLARE @intMinutesMax AS INT;
    SET @intMinutesMax = dbo.ufn_Minutes('5983-01-24 02:07:00');
 
    IF @intMinutes >= @intMinutesMax
    BEGIN
        SET @intMinutes = @intMinutesMax;
    END
 
    RETURN DATEADD(MINUTE, @intMinutes, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_MinutesOfDay', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_MinutesOfDay;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间基于所在当前日午夜零时的分钟数
-- 功能: 运行在SQL Server 2005+。
--       结果值从0开始计数,包括0、1、2、3、1439。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @sintMinutesOfDay = dbo.fn_MinutesOfDay(GETDATE());
--==================================
CREATE FUNCTION dbo.ufn_MinutesOfDay
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS SMALLINT
AS
BEGIN
    RETURN DATEPART(HOUR, @dtmDate) * 60 + DATEPART(MINUTE, @dtmDate);
END
GO
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-02-14 02:14:18';
 
SELECT
    @dtmDate AS 'The Current DateTime'
    ,dbo.ufn_Minutes(@dtmDate) AS 'Minutes'
    ,dbo.ufn_Minutes2Date(dbo.ufn_Minutes(@dtmDate)) AS 'DateTime Mapping Minutes'
    ,dbo.ufn_MinutesOfDay(@dtmDate) AS 'Minutes Of The Current Day';
 
SET @dtmDate = '2016-05-20 05:20:48';
 
SELECT 
    @dtmDate AS 'The Current DateTime'
    ,dbo.ufn_Minutes(@dtmDate) AS 'Minutes'
    ,dbo.ufn_Minutes2Date(dbo.ufn_Minutes(@dtmDate)) AS 'DateTime Mapping Minutes'
    ,dbo.ufn_MinutesOfDay(@dtmDate) AS 'Minutes Of The Current Day';
GO
 
以上3个函数的测试效果,如下图:
 
    小时时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Hours', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Hours;
END
GO
 
--==================================
-- 功能: 获得指定的日期时间基于基准日期的总小时数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intHours = dbo.ufn_Hours('2008-01-14 17:45')  -- 947033
--==================================
CREATE FUNCTION dbo.ufn_Hours 
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS INT
    --$Encode$--
AS
BEGIN
    RETURN DATEDIFF(HOUR, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Hours2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Hours2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于基准日期对应的日期时间
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0;
--       如果指定的整数值大于“9999-12-31 23:00:00”对应的整数值时,则其值默认设置为“9999-12-31 23:00:00”对应的整数值。
--       结果值为基于默认基准日期开始计数的日期。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.fn_Hours2Date(947033) -- '2008-01-14 17:00'
--==================================
CREATE FUNCTION dbo.ufn_Hours2Date 
(
    @intHours INT                        -- 指定的整数值
) RETURNS DATETIME
AS
BEGIN
    SET @intHours = dbo.ufn_GetValidDateNum(@intHours);
 
    DECLARE @intMaxHours AS INT;
    SET @intMaxHours = dbo.ufn_Hours(dbo.ufn_GetMaxDateTime());
 
    IF @intHours >= @intMaxHours
    BEGIN
        SET @intHours = @intMaxHours;
    END
 
    RETURN DATEADD(HOUR, @intHours, dbo.ufn_GetDefaultBasedate());
END
GO
 
 
IF OBJECT_ID(N'dbo.ufn_HoursOfDay', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_HoursOfDay;
END
GO
 
--==================================
-- 功能: 获取指定的日期日期基于所在当期日午夜零时的小时数
-- 说明: 运行在SQL Server 2005+。
--       结果值从0开始计数,包括0、1、2、……、23。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintHoursOfDay = dbo.ufn_HoursOfDay(GETDATE());
--==================================
CREATE FUNCTION dbo.ufn_HoursOfDay
(
    @dtmDate DATETIME            -- 指定的日期时间
)
RETURNS TINYINT
AS
BEGIN
    RETURN DATEPART(HOUR, @dtmDate);
END
GO
 
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2014-02-14 6:12:00'
 
SELECT 
    @dtmDate AS 'The Current DateTime'
    ,dbo.ufn_Hours(@dtmDate) AS 'Hours'
    ,dbo.ufn_Hours2Date(dbo.ufn_Hours(@dtmDate)) AS 'DateTime Mapping Hours'
    ,dbo.ufn_HoursOfDay(@dtmDate) AS 'Hours Of The Current Day';
 
SET @dtmDate = '2014-05-20 8:18:00'
 
SELECT
    @dtmDate AS 'The Current DateTime'
    ,dbo.ufn_Hours(@dtmDate) AS 'Hours'
    ,dbo.ufn_Hours2Date(dbo.ufn_Hours(@dtmDate)) AS 'DateTime Mapping Hours'
    ,dbo.ufn_HoursOfDay(@dtmDate) AS 'Hours Of The Current Day'
GO
 
以上3个函数的测试效果,如下图:
 
    周以上时间粒度基准日期有关函数,T-SQL代码如下:   
IF OBJECT_ID(N'dbo.ufn_FirstDayOfPeriodTable', 'IF') IS NOT NULL
BEGIN
    DROP FUNCTION ufn_FirstDayOfPeriodTable;
END
GO
 
--==================================
-- 功能: 旬首日索引表
-- 说明: 运行在SQL Server 2005+。
--       结果值为表数据,列名为FirstDayOfPeriod,其字段列(域)值包括1、11、21这3个数字,其字段列值对应每年每个旬的第一天。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT * FROM dbo.ufn_FirstDayOfPeriodTable();
--==================================
CREATE FUNCTION dbo.ufn_FirstDayOfPeriodTable
(
 
) RETURNS TABLE
    --$Encode$--
    RETURN ( 
        SELECT 1 AS FirstDayOfPeriod
        UNION ALL SELECT 11
        UNION ALL SELECT 21
    );
GO
 
IF OBJECT_ID(N'dbo.ufn_FirstDayOfPeriod', N'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_FirstDayOfPeriod;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前旬的第一个日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、11、21。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT @tintFirstDayOfPeriod = ufn_FirstDayOfPeriod(@dtmDate);
--==================================
CREATE FUNCTION dbo.ufn_FirstDayOfPeriod
(
    @dtmDate DATETIME                    -- 指定的日期时间
 
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE @tintFirstDayOfPeriod AS TINYINT;
    SET @tintFirstDayOfPeriod = 1;
 
    SELECT TOP 1 @tintFirstDayOfPeriod = FirstDayOfPeriod
    FROM dbo.ufn_FirstDayOfPeriodTable()
    WHERE FirstDayOfPeriod <= DAY(@dtmDate)
    ORDER BY FirstDayOfPeriod DESC;
 
    RETURN @tintFirstDayOfPeriod;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_BasedateOfPeriod', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_BasedateOfPeriod;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在旬的基准日期
-- 说明: 运行在SQL Server 2005+。
--       结果值为旬基准日,即每个旬第一天对应的日期。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmBasedateOfPeriod = dbo.ufn_BasedateOfPeriod('2016-01-12');
--==================================
CREATE FUNCTION dbo.ufn_BasedateOfPeriod
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS DATETIME
    --$Encode$--
BEGIN
    RETURN CONVERT(DATETIME, CAST(YEAR(@dtmDate) AS CHAR(4)) + '-' + CAST(MONTH(@dtmDate) AS VARCHAR(2)) + '-' + CAST(dbo.ufn_FirstDayOfPeriod(@dtmDate) AS VARCHAR(2)), 120);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_BasedateOfMonth', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_BasedateOfMonth;
END
GO
 
--==================================
-- 功能: 获取指定日期时间所在月的基准日期
-- 说明: 运行在SQL Server 2005+。
--       结果值为月基准日,即每个月第一天对应的日期。 
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmBasedateOfMonth = dbo.ufn_BasedateOfMonth('2016-01-12');
--==================================
CREATE FUNCTION dbo.ufn_BasedateOfMonth
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS DATETIME
    --$Encode$--
BEGIN
    RETURN CONVERT(DATETIME, CAST(YEAR(@dtmDate) AS CHAR(4)) + '-' + CAST(MONTH(@dtmDate) AS VARCHAR(2)) + '-' + CAST(1 AS CHAR(1)), 120);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_FirstMonthOfQuarterTable', 'IF') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_FirstMonthOfQuarterTable;
END
GO
 
--==================================
-- 功能: 季首月索引表
-- 说明: 运行在SQL Server 2005+。
--       结果值为表数据,列名为FirstMonthOfQuarter,其字段列(域)值包括1、4、7、10这4个数字,其字段列值对应每年每个季的第一个月份。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT * FROM dbo.ufn_FirstMonthOfQuarterTable();
--==================================
CREATE FUNCTION dbo.ufn_FirstMonthOfQuarterTable
(
) RETURNS TABLE
    --$Encode$--
    RETURN ( 
        SELECT 1 AS FirstMonthOfQuarter
        UNION ALL SELECT 4
        UNION ALL SELECT 7
        UNION ALL SELECT 10
    );
GO
 
IF OBJECT_ID(N'dbo.ufn_FirstMonthOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_FirstMonthOfQuarter;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前季度的第一个月索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、4、7、10。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT @tintFirstMonthOfQuarter = ufn_FirstMonthOfQuarter(@dtmDate);
--==================================
CREATE FUNCTION dbo.ufn_FirstMonthOfQuarter
(
    @dtmDate DATETIME                    -- 指定的日期时间
 
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE @tintFirstMonthOfQuarter AS TINYINT;
    SET @tintFirstMonthOfQuarter = 1;
 
    SELECT TOP 1 @tintFirstMonthOfQuarter = FirstMonthOfQuarter
    FROM dbo.ufn_FirstMonthOfQuarterTable() 
    WHERE FirstMonthOfQuarter <= MONTH(@dtmDate)
    ORDER BY FirstMonthOfQuarter DESC;
 
    RETURN @tintFirstMonthOfQuarter;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_BasedateOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_BasedateOfQuarter;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前季的季基准日期
-- 说明: 运行在SQL Server 2005+。
--       结果值格式"XXXX-01-01",包括:"XXXX-01-01"、"XXXX-04-01"、"XXXX-07-01"、"XXXX-10-01"。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT @tintFirstMonthOfQuarter = ufn_BasedateOfQuarter(@dtmDate);
--==================================
CREATE FUNCTION dbo.ufn_BasedateOfQuarter
(
    @dtmDate DATETIME                    -- 指定的日期时间
 
) RETURNS DATETIME
    --$Encode$--
BEGIN
    RETURN  CONVERT(DATETIME, CAST(YEAR(@dtmDate) AS CHAR(4)) + '-' + CAST(dbo.ufn_FirstMonthOfQuarter(@dtmDate) AS VARCHAR(2)) + '-' + CAST(1 AS CHAR(1)), 120);
END
GO
 
 
IF OBJECT_ID(N'dbo.ufn_BasedateOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_BasedateOfYear;
END
GO
--==================================
-- 功能: 获取指定日期时间所在年的基准日期
-- 说明: 结果值是每个年的基准日,每个年第一天对应的日期。 
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmBasedateOfYear = dbo.ufn_BasedateOfYear('2016-01-12');
--==================================
CREATE FUNCTION dbo.ufn_BasedateOfYear
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS DATETIME
    --$Encode$--
BEGIN
    RETURN CONVERT(DATETIME, CAST(YEAR(@dtmDate) AS CHAR(4)) + '-' + CAST(1 AS CHAR(1)) +  '-' + CAST(1 AS char(1)), 120);
END
GO
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-14';
 
SELECT 
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_BasedateOfPeriod(@dtmDate) AS 'Basedate Of The Current Period'
    ,dbo.ufn_BasedateOfMonth(@dtmDate) AS 'Basedate Of The Current Month'
    ,dbo.ufn_BasedateOfQuarter(@dtmDate) AS 'Basedate Of the Current Quarter'
    ,dbo.ufn_BasedateOfYear(@dtmDate) AS 'Basedate Of the Current Year'
    ,dbo.ufn_GetMinDateTime() AS 'Basedate Of the Current Date';
 
SET @dtmDate = '2016-4-30';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_BasedateOfPeriod(@dtmDate) AS 'Basedate Of The Current Period'
    ,dbo.ufn_BasedateOfMonth(@dtmDate) AS 'Basedate Of The Current Month'
    ,dbo.ufn_BasedateOfQuarter(@dtmDate) AS 'Basedate Of the Current Quarter'
    ,dbo.ufn_BasedateOfYear(@dtmDate) AS 'Basedate Of the Current Year'
    ,dbo.ufn_GetMinDateTime() AS 'Basedate Of the Current Date';
GO
 
以上几个函数的测试效果,如下图:
    
    天时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Days', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Days;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总天数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intDays = dbo.ufn_Days('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Days
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS INT
    --$Encode$--
AS
BEGIN
    RETURN DATEDIFF(DAY, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Days2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Days2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0。
--       如果指定的整数值大于最大日期时间对应的整数值时,则其值默认设置为最大日期时间对应的整数值。
--       结果值为基于默认基准日期开始计数的日期。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Days2Date(39459) --'2008-01-14'
--==================================
CREATE FUNCTION dbo.ufn_Days2Date 
(
    @intDays INT                -- 指定的整数值
) RETURNS DATETIME
    --$Encode$--
AS
BEGIN
    SET @intDays = dbo.ufn_GetValidDateNum(@intDays);
 
    DECLARE @intMaxDays AS INT;
    SET @intMaxDays = dbo.ufn_Days(dbo.ufn_GetMaxDateTime());
 
    IF @intDays >= @intMaxDays
    BEGIN
        SET @intDays = @intMaxDays;
    END
 
    RETURN DATEADD(DAY, @intDays, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_DayOfWeek', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfWeek;
END
GO
 
--==================================
-- 功能: 获取指定日期时间的所在当前周的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1到7,分别对应从周一到周日,该值与@@DATEFISRT配置函数值保持一致。
--       使用(@@datefirt + datepart(weekday, @dtmDate))%7的结果值从2、3、4、5、6、0、1
--       分别对应周一、周二、周三、周四、周五、周六、周日。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_DayOfWeek('2017-01-07') -- 4(表示星期四)
--==================================
CREATE FUNCTION dbo.ufn_DayOfWeek
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE    @tintRemainder AS TINYINT;
    SET @tintRemainder = (@@DATEFIRST + DATEPART(WEEKDAY, @dtmDate)) % 7;
    IF @tintRemainder <= 1
    BEGIN
        SET @tintRemainder = @tintRemainder + 6;
    END
    ELSE
    BEGIN
        SET @tintRemainder = @tintRemainder - 1;
    END
 
    RETURN @tintRemainder;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_DayOfPeriod', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfPeriod;
END
GO
 
--==================================
-- 功能: 获得指定日期时间在当前旬的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3、……、8、9、10、11。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intPeriods = dbo.ufn_DayOfPeriod('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_DayOfPeriod
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
AS
BEGIN
    --RETURN DAY(@dtmDate) - (dbo.ufn_PeriodOfMonth(@dtmDate) - 1) * 10;
    RETURN DATEDIFF(DAY, dbo.ufn_BasedateOfPeriod(@dtmDate), @dtmDate) + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_DayOfMonth', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfMonth;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前月的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3.……、28、29、30、31。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @sintDayOfYear = dbo.ufn_DayOfMonth('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_DayOfMonth
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    RETURN DAY(@dtmDate);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_DayOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfQuarter;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在季的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3.……、89、90、91、92。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
--==================================
CREATE FUNCTION dbo.ufn_DayOfQuarter
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    RETURN DATEDIFF(DAY, dbo.ufn_BasedateOfQuarter(@dtmDate), @dtmDate) + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_DayOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfYear;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前年的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3.……、364、365、366。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @sintDayOfYear = dbo.ufn_DayOfYear('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_DayOfYear
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS SMALLINT
    --$Encode$--
BEGIN
    RETURN DATEPART(DAYOFYEAR, @dtmDate);
END
GO
 
 
IF OBJECT_ID(N'dbo.ufn_DayOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_DayOfDate;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前日期的日索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3.……、3652057、3652058、3652059。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @inntDayOfDate = dbo.ufn_DayOfDate('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_DayOfDate
(
    @dtmDate DATETIME
) RETURNS INT
    --$Encode$--
BEGIN
    RETURN DATEDIFF(DAY, dbo.ufn_GetMinDateTime(), dbo.ufn_GetValidDate(@dtmDate)) + 1
END
GO
 
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-14';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Days(@dtmDate) AS 'Days'
    ,dbo.ufn_Days2Date(dbo.ufn_Days(@dtmDate)) AS 'Date Mapping Days'
    ,dbo.ufn_DayOfWeek(@dtmDate) AS 'Day Of The Current Week'
    ,dbo.ufn_DayOfPeriod(@dtmDate) AS 'Day Of The Current Period'
    ,dbo.ufn_DayOfMonth(@dtmDate) AS 'Day Of The Current Month'
    ,dbo.ufn_DayOfQuarter(@dtmDate) AS 'Day Of The Current Quarter'
    ,dbo.ufn_DayOfYear(@dtmDate) AS 'Day Of The Current Year'
    ,dbo.ufn_DayOfDate(@dtmDate) AS 'Day Of The Current Date';
 
SET @dtmDate = '2016-03-14';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Days(@dtmDate) AS 'Days'
    ,dbo.ufn_Days2Date(dbo.ufn_Days(@dtmDate)) AS 'Date Mapping Days'
    ,dbo.ufn_DayOfWeek(@dtmDate) AS 'Day Of The Current Week'
    ,dbo.ufn_DayOfPeriod(@dtmDate) AS 'Day Of The Current Period'
    ,dbo.ufn_DayOfMonth(@dtmDate) AS 'Day Of The Current Month'
    ,dbo.ufn_DayOfQuarter(@dtmDate) AS 'Day Of The Current Quarter'
    ,dbo.ufn_DayOfYear(@dtmDate) AS 'Day Of The Current Year'
    ,dbo.ufn_DayOfDate(@dtmDate) AS 'Day Of The Current Date';
GO
 
以上几个函数的测试效果,如下图:
 
    周时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Weeks', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Weeks;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总周数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intDays = dbo.ufn_Weeks('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Weeks
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS INT
    --$Encode$--
AS
BEGIN
    RETURN dbo.ufn_Days(@dtmDate) / 7;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Weeks2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Weeks2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0;
--       如果指定的整数值大于最大日期时间对应的整数值时,则其值默认设置为最大日期时间对应的整数值。
--       结果值为基于默认基准日期开始计数的周基准日期,也就是周一对应的日期。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Weeks2Date(39459);
--==================================
CREATE FUNCTION dbo.ufn_Weeks2Date
(
    @intWeeks INT                    -- 指定的整数值
) RETURNS DATETIME
    --$Encode$--
AS
BEGIN
    SET @intWeeks = dbo.ufn_GetValidDateNum(@intWeeks);
 
    DECLARE @intMaxWeeks AS INT;
    SET @intMaxWeeks = dbo.ufn_Weeks(dbo.ufn_GetMaxDateTime());
 
    IF @intWeeks >= @intMaxWeeks
    BEGIN
        SET @intWeeks = @intMaxWeeks;
    END
 
    RETURN DATEADD(DAY, @intWeeks * 7, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_WeekOfPeriod', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_WeekOfPeriod;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前旬的周索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintWeekOfPeriod = dbo.ufn_WeekOfPeriod('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_WeekOfPeriod
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE @tintWeekOffsetOfPeriod AS TINYINT;
    SET @tintWeekOffsetOfPeriod = DATEDIFF(WEEK, dbo.ufn_BasedateOfPeriod(@dtmDate), @dtmDate);
 
    IF dbo.ufn_DayOfWeek(@dtmDate) = 7 AND @tintWeekOffsetOfPeriod >= 1
    BEGIN
        SET @tintWeekOffsetOfPeriod = @tintWeekOffsetOfPeriod - 1;
    END
 
    RETURN @tintWeekOffsetOfPeriod + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_WeekOfMonth', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_WeekOfMonth;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前月的周索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3、4、5
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintWeekOfMonth = dbo.ufn_WeekOfMonth('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_WeekOfMonth
(
    @dtmDate DATETIME
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE @tintWeekOffsetOfMonth AS TINYINT;
    SET @tintWeekOffsetOfMonth = DATEDIFF(WEEK, dbo.ufn_BasedateOfMonth(@dtmDate), @dtmDate);
 
    IF dbo.ufn_DayOfWeek(@dtmDate) = 7 AND @tintWeekOffsetOfMonth >= 1
    BEGIN
        SET @tintWeekOffsetOfMonth = @tintWeekOffsetOfMonth - 1;
    END
 
    RETURN @tintWeekOffsetOfMonth + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_WeekOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_WeekOfQuarter;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前季的周索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、3、4、5、6、7、7、……。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintWeekOfQuarter = dbo.ufn_WeekOfQuarter('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_WeekOfQuarter
(
    @dtmDate DATETIME
) RETURNS TINYINT
    --$Encode$--
BEGIN
    DECLARE @tintWeekOffsetOfQuarter AS TINYINT;
    SET @tintWeekOffsetOfQuarter = DATEDIFF(WEEK, dbo.ufn_BasedateOfQuarter(@dtmDate), @dtmDate);
 
    IF dbo.ufn_DayOfWeek(@dtmDate) = 7 AND @tintWeekOffsetOfQuarter >= 1
    BEGIN
        SET @tintWeekOffsetOfQuarter = @tintWeekOffsetOfQuarter - 1;
    END
 
    RETURN @tintWeekOffsetOfQuarter + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_WeekOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_WeekOfYear;
END
GO
 
--==================================
-- 功能: 获取指定日期属于当前年的周索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,一年最多1-53周。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_WeekOfYear('2016-01-07');
--==================================
CREATE FUNCTION dbo.ufn_WeekOfYear
(
    @dtmDate DATETIME
) RETURNS TINYINT
    --$Encode$--
AS
BEGIN
    DECLARE @tintWeekOffsetOfYear AS TINYINT;
    SET @tintWeekOffsetOfYear = DATEDIFF(WEEK, dbo.ufn_BasedateOfYear(@dtmDate), @dtmDate);
 
    IF dbo.ufn_DayOfWeek(@dtmDate) = 7 AND @tintWeekOffsetOfYear >= 1
    BEGIN
        SET @tintWeekOffsetOfYear = @tintWeekOffsetOfYear - 1;
    END
 
    RETURN @tintWeekOffsetOfYear + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_WeekOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_WeekOfDate;
END
GO
 
--==================================
-- 功能: 获取指定日期属于当前日历的周索引
-- 说明: 运行在SQL Server 2008+。
--       结果值从1开始计数,包括1、2、3、4、……。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SELECT dbo.ufn_WeekOfDate('2016-01-07');
--==================================
CREATE FUNCTION dbo.ufn_WeekOfDate
(
    @dtmDate DATETIME
) RETURNS INT
    --$Encode$--
AS
BEGIN
    DECLARE @intWeekOffsetOfDate AS INT;
    SET @intWeekOffsetOfDate = DATEDIFF(WEEK, dbo.ufn_GetMinDateTime(), @dtmDate);
 
    IF (@@DATEFIRST + DATEPART(WEEKDAY, @dtmDate)) % 7 = 1 AND @intWeekOffsetOfDate >= 1
    BEGIN
        SET @intWeekOffsetOfDate = @intWeekOffsetOfDate - 1;
    END
 
    RETURN @intWeekOffsetOfDate + 1;
END
GO
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-15';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Weeks(@dtmDate) AS 'Weeks'
    ,dbo.ufn_Weeks2Date(dbo.ufn_Weeks(@dtmDate)) AS 'Date Mapping Weeks'
    ,dbo.ufn_WeekOfPeriod(@dtmDate) AS 'Week Of The Current Period'
    ,dbo.ufn_WeekOfMonth(@dtmDate) AS 'Week Of The Current Month'
    ,dbo.ufn_WeekOfQuarter(@dtmDate) AS 'Week Of The Current Quarter'
    ,dbo.ufn_WeekOfYear(@dtmDate) AS 'Week Of The Current Year'
    ,dbo.ufn_WeekOfDate(@dtmDate) AS 'Week Of The Current Date';
 
SET @dtmDate = '2016-01-31';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Weeks(@dtmDate) AS 'Weeks'
    ,dbo.ufn_Weeks2Date(dbo.ufn_Weeks(@dtmDate)) AS 'Date Mapping Weeks'
    ,dbo.ufn_WeekOfPeriod(@dtmDate) AS 'Week Of The Current Period'
    ,dbo.ufn_WeekOfMonth(@dtmDate) AS 'Week Of The Current Month'
    ,dbo.ufn_WeekOfQuarter(@dtmDate) AS 'Week Of The Current Quarter'
    ,dbo.ufn_WeekOfYear(@dtmDate) AS 'Week Of The Current Year'
    ,dbo.ufn_WeekOfDate(@dtmDate) AS 'Week Of The Current Date';
GO
 
测试以上函数的效果,如下图:
    旬时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_PeriodOfMonth', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_PeriodOfMonth;
END
GO
 
--==================================
-- 功能: 获得指定日期时间在当前月的旬索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,1、2、3分别对应上、中、下的旬索引。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intPeriods = dbo.ufn_PeriodOfMonth('2008-01-14')
--==================================
CREATE FUNCTION [dbo].[ufn_PeriodOfMonth] 
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
AS
BEGIN
    --当前月的日索引,从1开始计数,,包括1、2、3、……、28、29、30、31
    DECLARE @tintDayOfMonth AS TINYINT;
    SET @tintDayOfMonth = DAY(@dtmDate);
    -- 旬偏移索引,0:上旬,1:中旬,2:下旬
    DECLARE @tintPeriodOffsetIndexID AS INT;
    SET @tintPeriodOffsetIndexID = DAY(@dtmDate) / 10
 
    IF @tintDayOfMonth IN (10, 20, 30, 31)
    BEGIN
        SET @tintPeriodOffsetIndexID = @tintPeriodOffsetIndexID - 1;
    END
 
    RETURN @tintPeriodOffsetIndexID + 1;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Periods', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Periods;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总旬数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intPeriods = dbo.ufn_Periods('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Periods
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS INT
    --$Encode$--
AS
BEGIN
    RETURN DATEDIFF(MONTH, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate)) * 3 + (dbo.ufn_PeriodOfMonth(@dtmDate) - 1);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Periods2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Periods2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的旬基准日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0;
--       如果指定的整数值大于“9999-12-31”对应的整数值时,则其值默认设置为“9999-12-31”对应的整数值;
--       结果值为基于默认基准日期开始计数的日期;
--       旬基准日期是指一个月份中第1天、第11天和第21天对应的日期,比如'2016-02'月份的3个旬基准日期分别为'2016-02-01','2016-02-11','2016-02-21'。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Periods2Date(2705) --'1975-02-21'
--==================================
CREATE FUNCTION dbo.ufn_Periods2Date 
(
    @intPeriods INT        -- 指定的整数值
) RETURNS DATETIME
AS
BEGIN
    SET @intPeriods = dbo.ufn_GetValidDateNum(@intPeriods);
 
    DECLARE @intMaxPeriods AS INT;
    SET @intMaxPeriods = dbo.ufn_Periods(dbo.ufn_GetMaxDateTime());
 
    IF @intPeriods >= @intMaxPeriods
    BEGIN
        SET @intPeriods = @intMaxPeriods;
    END
 
    RETURN DATEADD(DAY, (@intPeriods - @intPeriods / 3 * 3) * 10, DATEADD(MONTH, @intPeriods / 3, dbo.ufn_GetDefaultBasedate()));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_PeriodOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_PeriodOfQuarter;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前季的旬索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、……、7、8、9。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintPeriodOfQuarter = dbo.ufn_PeriodOfQuarter('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_PeriodOfQuarter
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    RETURN (MONTH(@dtmDate) - dbo.ufn_FirstMonthOfQuarter(@dtmDate)) * 3 + dbo.ufn_PeriodOfMonth(@dtmDate);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_PeriodOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_PeriodOfYear;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前年的旬索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、……、34、35、36。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintPeriodOfYear = dbo.ufn_PeriodOfYear('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_PeriodOfYear
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    RETURN (MONTH(@dtmDate) - 1) * 3 + dbo.ufn_PeriodOfMonth(@dtmDate);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_PeriodOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_PeriodOfDate;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前日期的旬索引
-- 说明: 运行在SQL Server 2008+。
--       结果值从1开始计数,包括1、2、3.……、359962、359963、359964。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @inntDayOfDate = dbo.ufn_DayOfDate('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_PeriodOfDate
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS INT
    --$Encode$--
BEGIN
    SET @dtmDate = dbo.ufn_GetValidDate(@dtmDate);
 
    RETURN DATEDIFF(MONTH, dbo.ufn_GetMinDateTime(), @dtmDate) * 3 + dbo.ufn_PeriodOfMonth(@dtmDate);
END
GO
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-15';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Periods(@dtmDate) AS 'Periods'
    ,dbo.ufn_Periods2Date(dbo.ufn_Periods(@dtmDate)) AS 'Date Mapping Periods'
    ,dbo.ufn_PeriodOfMonth(@dtmDate) AS 'Period Of The Current Month'
    ,dbo.ufn_PeriodOfQuarter(@dtmDate) AS 'Period Of The Current Quarter'
    ,dbo.ufn_PeriodOfYear(@dtmDate) AS 'Period Of The Current Year'
    ,dbo.ufn_PeriodOfDate(@dtmDate) AS 'Period Of The Current Date';
 
SET @dtmDate = '2016-01-31';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Periods(@dtmDate) AS 'Periods'
    ,dbo.ufn_Periods2Date(dbo.ufn_Periods(@dtmDate)) AS 'Date Mapping Periods'
    ,dbo.ufn_PeriodOfMonth(@dtmDate) AS 'Period Of The Current Month'
    ,dbo.ufn_PeriodOfQuarter(@dtmDate) AS 'Period Of The Current Quarter'
    ,dbo.ufn_PeriodOfYear(@dtmDate) AS 'Period Of The Current Year'
    ,dbo.ufn_PeriodOfDate(@dtmDate) AS 'Period Of The Current Date';
GO
 
测试以上函数的效果,如下图:
 
    月时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Months', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Months;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总月数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intMonths = dbo.ufn_Months('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Months 
(
    @dtmDate DATETIME                -- 指定的日期时间
) RETURNS INT
AS
BEGIN
    RETURN DATEDIFF(MONTH, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Months2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Months2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的月基准日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0。
--       如果指定的整数值大于最大日期时间对应的整数值时,则其值默认设置为最大日期时间对应的整数值。
--       结果值为基于默认基准日期开始计数的日期。
--       月基准日期是指一个月份中第1天对应的日期,比如'2016-02'月份的月旬基准日期为'2016-02-01'。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Months2Date(1296) --'2008-01-01'
--==================================
CREATE FUNCTION dbo.ufn_Months2Date 
(
    @intMonths INT                -- 指定的整数值
) RETURNS DATETIME
AS
BEGIN
    SET @intMonths = dbo.ufn_GetValidDateNum(@intMonths);
 
    DECLARE @intMaxMonths AS INT;
    SET @intMaxMonths = dbo.ufn_Months(dbo.ufn_GetMaxDateTime());
 
    IF @intMonths >= @intMaxMonths
    BEGIN
        SET @intMonths = @intMaxMonths;
    END
 
    RETURN DATEADD(MONTH, @intMonths, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_MonthOfQuarter', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_MonthOfQuarter;
END
GO
 
--==================================
-- 功能: 获得一个日期时间的月份在当前季度的月索引
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL时,则其值默认设置为默认基准日期。
--       结果值从1开始计数,包括1、2、3。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_MonthOfQuarter(2008-01-01);
--==================================
CREATE FUNCTION dbo.ufn_MonthOfQuarter
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
AS
BEGIN
    SET @dtmDate = dbo.ufn_GetValidDate(@dtmDate);
    DECLARE @tintMonthOfQuarter AS TINYINT;
    SET @tintMonthOfQuarter = 1;
 
    SET @tintMonthOfQuarter =  MONTH(@dtmDate) % 3;
 
    IF @tintMonthOfQuarter = 0
    BEGIN
        SET @tintMonthOfQuarter = 3;
    END
 
    RETURN @tintMonthOfQuarter;
END
GO
 
IF OBJECT_ID(N'dbo.ufn_MonthOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_MonthOfYear;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前年的月索引
-- 说明: 运行在SQL Server 2005+。
--       结果值从1开始计数,包括1、2、……、9、10、11、12。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintMonthOfYear = dbo.ufn_MonthOfYear('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_MonthOfYear
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS TINYINT
    --$Encode$--
BEGIN
    RETURN MONTH(@dtmDate);
END
GO
 
 
IF OBJECT_ID(N'dbo.ufn_MonthOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_MonthOfDate;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前日期的月索引
-- 说明: 运行在SQL Server 2008+。
--       结果值从1开始计数,包括1、2、3.……、119986、119987、119988。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intMonthOfDate = dbo.ufn_MonthOfDate('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_MonthOfDate
(
    @dtmDate DATETIME
) RETURNS INT
    --$Encode$--
BEGIN
    RETURN DATEDIFF(MONTH, dbo.ufn_GetMinDateTime(), dbo.ufn_GetValidDate(@dtmDate)) + 1;
END
GO
 
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-15';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Months(@dtmDate) AS 'Months'
    ,dbo.ufn_Months2Date(dbo.ufn_Months(@dtmDate)) AS 'Date Mapping Months'
    ,dbo.ufn_MonthOfQuarter(@dtmDate) AS 'Month Of The Current Quarter'
    ,dbo.ufn_MonthOfYear(@dtmDate) AS 'Month Of The Current Year'
    ,dbo.ufn_MonthOfDate(@dtmDate) AS 'Month Of The Current Date';
 
SET @dtmDate = '2016-09-30';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Months(@dtmDate) AS 'Months'
    ,dbo.ufn_Months2Date(dbo.ufn_Months(@dtmDate)) AS 'Date Mapping Months'
    ,dbo.ufn_MonthOfQuarter(@dtmDate) AS 'Month Of The Current Quarter'
    ,dbo.ufn_MonthOfYear(@dtmDate) AS 'Month Of The Current Year'
    ,dbo.ufn_MonthOfDate(@dtmDate) AS 'Month Of The Current Date';
GO
 
测试以上函数的效果,如下图:
 
    季时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Quarters', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Quarters;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总季数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期。
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intQuarters = dbo.ufn_Quarters('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Quarters
(
    @dtmDate DATETIME                    -- 指定的日期时间
) RETURNS INT
    --$Encode$--
AS
BEGIN
    RETURN DATEDIFF(QUARTER, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Quarters2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Quarters2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的季基准日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0。
--       如果指定的整数值大于最大日期时间对应的整数值时,则其值默认设置为最大日期时间对应的整数值。
--       结果值为基于默认基准日期开始计数的日期。
--       季基准日期是指所在季度的第一个月份中第1天对应的日期,比如'2016-06-08'月份的姐旬基准日期为'2016-04-01'。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.fn_Quarters2Date(300) --'1975-02-21'
--==================================
CREATE FUNCTION dbo.ufn_Quarters2Date 
(
    @intQuarters INT            -- 指定的整数值
) RETURNS DATETIME
    --$Encode$--
AS
BEGIN
    SET @intQuarters = dbo.ufn_GetValidDateNum(@intQuarters);
 
    DECLARE @intMaxQuarters AS INT;
    SET @intMaxQuarters = dbo.ufn_Quarters(dbo.ufn_GetMaxDateTime());
 
    IF @intQuarters >= @intMaxQuarters
    BEGIN
        SET @intQuarters = @intMaxQuarters;
    END
 
    RETURN DATEADD(QUARTER, @intQuarters, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_QuarterOfYear', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_QuarterOfYear;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前年内的旬索引
-- 说明: 运行在SQL Server 2005+。
--       结果从1开始计数,1、2、3、4分别表示第1季度、第2季度、第3季度、第4季度。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @tintQuarterOfYear = dbo.ufn_QuarterOfYear('2016-01-11');
--==================================
CREATE FUNCTION dbo.ufn_QuarterOfYear
(
    @dtmDate DATETIME                --指定的日期时间
) RETURNS TINYINT
    --$Encode$--
AS
BEGIN
    RETURN DATEPART(QUARTER, @dtmDate);
END
GO
 
IF OBJECT_ID(N'dbo.ufn_QuarterOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_QuarterOfDate;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在当前日期的季索引
-- 说明: 运行在SQL Server 2008+。
--       结果值从1开始计数,包括1、2、3.……、39994、39995、39996。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @intQuarterOfDate = dbo.ufn_QuarterOfDate('2016-01-11')
--==================================
CREATE FUNCTION dbo.ufn_QuarterOfDate
(
    @dtmDate DATETIME                --指定的日期时间
) RETURNS INT
    --$Encode$--
BEGIN
    RETURN DATEDIFF(QUARTER, dbo.ufn_GetMinDateTime(), dbo.ufn_GetValidDate(@dtmDate)) + 1;
END
GO
 
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-15';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Quarters(@dtmDate) AS 'Quarters'
    ,dbo.ufn_Quarters2Date(dbo.ufn_Quarters(@dtmDate)) AS 'Date Mapping Quarters'
    ,dbo.ufn_QuarterOfYear(@dtmDate) AS 'Quarter Of The Current Year'
    ,dbo.ufn_QuarterOfDate(@dtmDate) AS 'Quarter Of The Current Date';
 
SET @dtmDate = '2016-09-30';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Quarters(@dtmDate) AS 'Quarters'
    ,dbo.ufn_Quarters2Date(dbo.ufn_Quarters(@dtmDate)) AS 'Date Mapping Quarters'
    ,dbo.ufn_QuarterOfYear(@dtmDate) AS 'Quarter Of The Current Year'
    ,dbo.ufn_QuarterOfDate(@dtmDate) AS 'Quarter Of The Current Date';
GO
 
测试以上函数的效果,如下图:
 
    年时间粒度有关函数,T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_Years', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Years;
END
GO
 
--==================================
-- 功能: 获得指定日期时间基于默认基准日期的总年数(一个整数值)
-- 说明: 运行在SQL Server 2005+。
--       如果指定的日期时间为NULL或者小于默认基准日期时,则其值为默认基准日期
--       结果值为非负整数,从0开始计数。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @sintYears = dbo.ufn_Years('2008-01-14')
--==================================
CREATE FUNCTION dbo.ufn_Years 
(
    @dtmDate DATETIME            -- 指定的日期时间
) RETURNS SMALLINT
    --$Encode$--
AS
BEGIN
    RETURN DATEDIFF(YEAR, dbo.ufn_GetDefaultBasedate(), dbo.ufn_GetValidDate(@dtmDate));
END
GO
 
IF OBJECT_ID(N'dbo.ufn_Years2Date', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_Years2Date;
END
GO
 
--==================================
-- 功能: 获得一个整数值基于默认基准日期对应的年基准日期
-- 说明: 运行在SQL Server 2005+。
--       如果指定的整数值为NULL或为负整数时,则其值默认为0;
--       如果指定的整数值大于最大日期时间对应的整数值时,则其值默认设置为最大日期时间对应的整数值;
--       结果值为基于默认基准日期开始计数的日期;
--       年基准日期是指所在年的第一个月份中第1天对应的日期,比如'2016-06-08'月份的姐旬基准日期为'2016-01-01'。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @dtmDate = dbo.ufn_Years2Date(300) --'1975-02-21'
--==================================
CREATE FUNCTION dbo.ufn_Years2Date
(
    @sintYears SMALLINT            -- 指定的整数值
) RETURNS DATETIME
    --$Encode$--
AS
BEGIN
    SET @sintYears = dbo.ufn_GetValidDateNum(@sintYears);
 
    DECLARE @sintMaxYears AS SMALLINT;
    SET @sintMaxYears = dbo.ufn_Years(dbo.ufn_GetMaxDateTime());
 
    IF @sintYears >= @sintMaxYears
    BEGIN
        SET @sintYears = @sintMaxYears;
    END
 
    RETURN DATEADD(YEAR, @sintYears, dbo.ufn_GetDefaultBasedate());
END
GO
 
IF OBJECT_ID(N'dbo.ufn_YearOfDate', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION dbo.ufn_YearOfDate;
END
GO
 
--==================================
-- 功能: 获取指定的日期时间所在日期内的年索引
-- 说明: 运行在SQL Server 2005+。
--       结果从1开始计数,1、2、3、……、9998、9999。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
-- 调用: SET @sintYearOfDate = dbo.ufn_YearsOfDate('2016-01-11');
--==================================
CREATE FUNCTION dbo.ufn_YearOfDate
(
    @dtmDate DATETIME                --指定的日期时间
) RETURNS SMALLINT
    --$Encode$--
AS
BEGIN
    RETURN YEAR(@dtmDate);
END
GO
 
 
-- Test Code
DECLARE @dtmDate AS DATETIME;
SET @dtmDate = '2016-01-15';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Years(@dtmDate) AS 'Years'
    ,dbo.ufn_Years2Date(dbo.ufn_Years(@dtmDate)) AS 'Date Mapping Years'
    ,dbo.ufn_YearOfDate(@dtmDate) AS 'Year Of The Current Date';
 
SET @dtmDate = '2016-09-30';
 
SELECT
    @dtmDate AS 'The Current Date'
    ,dbo.ufn_Years(@dtmDate) AS 'Years'
    ,dbo.ufn_Years2Date(dbo.ufn_Years(@dtmDate)) AS 'Date Mapping Years'
    ,dbo.ufn_YearOfDate(@dtmDate) AS 'Year Of The Current Date';
GO
 
测试以上函数的效果,如下图:
 
日历数据表
 
    
根据以上各时间粒度有关的函数,汇总为一个日历数据表(Calendar),其表字段列如下表格:
序号 字段列
字段列类型
字段列说明
1
CalendarDate
datetime 日历日期[1900-01-01、1900-01-02、……、999-12-31]
2
Days
int
日期天数[0、1、2、……、最大值]
3
DayOfWeek
tinyint 周内日索引[1、2、……、7]
4
WorkDayFlag bit
工作日标志,1:工作日,0:非工作日
5
DayOfPeriod
tinyint
旬内日索引[1、2、……、8、9、10、11]
6
DayOfMonth
tinyint
月内日索引[1、2、……、28、29、30、31]
7
DayOfQuarter
tinyint
季内日索引[1、2、……88、89、90、91、92]
8
DayOfYear
smallint
年内日索引[1、2、……、364、365、366]
9 DayOfDate
int
日期内日索引[1、2、……、3652059]
10
Weeks
int
日期周数[0、1、2、……、最大值]
11 WeekOfPeriod
tinyint
旬内周索引[1、2、3]
12
WeekOfMonth
tinyint
月内周索引[1、2、3、4、5]
13
WeekOfQuarter
tinyint
季内周索引[1、2、……、34、35、36、37]
14 WeekOfYear
tinyint
年内周索引[1、2、……、51、52、53]
15
WeekOfDate
int
日期内周索引[1、2、……、521723]
16
Periods
int
日期旬数[0、1、2、……、最大值]
17 PeriodOfMonth
tinyint
月内旬索引[1、2、3]
18
PeriodOfQuarter
tinyint
季内旬索引[1、2、3、4、5、6、7、8、9]
19
PeriodOfYear
tinyint
年内旬索引[1、2、……、35、36]
20
PeriodOfDate
int
日期内旬索引[1、2、……、359964]
21
Months
int
日期月数[0、1、2、……、最大值]
22
MonthOfQuarter
tinyint
季内月索引[1、2、3]
23
MonthOfYear
tinyint
年内月索引[1、2、……、11、12]
24
MonthOfDate
int
日期内月索引[1、2、……、119988]
25
Quarters
int
日期季数[0、1、2、……、最大值]
26
QuarterOfYear
tinyint
年内季索引[1、2、3、4]
27
QuarterOfDate
int
日期内季索引[1、2、……、39996]
28
Years
smallint
日期年数[0、1、2、……、最大值]
29
YearOfDate smallint 日期内年索引[1、2、……、9999]
日历数据表创建的T-SQL脚本如下:
IF OBJECT_ID(N'dbo.Calendar', 'U') IS NOT NULL
BEGIN    
    DROP TABLE dbo.Calendar;
END
GO
 
CREATE TABLE dbo.Calendar (
    CalendarDate DATETIME NOT NULL,
    [Days] INT NOT NULL,
    [DayOfWeek] TINYINT NOT NULL,
    WorkDayFlag BIT NOT NULL,
    DayOfPeriod TINYINT NOT NULL,
    [DayOfMonth] TINYINT NOT NULL,
    DayOfQuarter TINYINT NOT NULL,
    [DayOfYear] SMALLINT NOT NULL,
    DayOfDate INT NOT NULL,
    Weeks INT NOT NULL,
    WeekOfPeriod TINYINT NOT NULL,
    WeekOfMonth TINYINT NOT NULL,
    WeekOfQuarter TINYINT NOT NULL,
    WeekOfYear TINYINT NOT NULL,
    WeekOfDate INT NOT NULL,
    Periods INT NOT NULL,
    PeriodOfMonth TINYINT NOT NULL,
    PeriodOfQuarter TINYINT NOT NULL,
    PeriodOfYear TINYINT NOT NULL,
    PeriodOfDate INT NOT NULL,
    Months INT NOT NULL,
    MonthOfQuarter TINYINT NOT NULL,
    MonthOfYear TINYINT NOT NULL,
    MonthOfDate INT NOT NULL,
    Quarters INT NOT NULL,
    QuarterOfYear TINYINT NOT NULL,
    QuarterOfDate INT NOT NULL,
    Years SMALLINT NOT NULL,
    YearOfDate SMALLINT NOT NULL,
    TagID INT NOT NULL,
    FlagID INT NOT NULL    
);
 
IF OBJECT_ID(N'PK_U_CL_Calendar_Days', N'PK') IS NULL
BEGIN
    ALTER TABLE [dbo].[Calendar] ADD CONSTRAINT [PK_U_CL_Calendar_Days] PRIMARY KEY CLUSTERED 
    (
        [Days] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) 
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_U_NCL_Calendar_CalendarDate')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_U_NCL_Calendar_CalendarDate] ON [dbo].[Calendar]
    (
        [CalendarDate] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_Weeks')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_Weeks] ON [dbo].[Calendar]
    (
        [Weeks] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_Periods')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_Periods] ON [dbo].[Calendar]
    (
        [Periods] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_Months')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_Months] ON [dbo].[Calendar]
    (
        [Months] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_Quarters')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_Quarters] ON [dbo].[Calendar]
    (
        [Quarters] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_Years')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_Years] ON [dbo].[Calendar]
    (
        [Years] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Calendar]', N'U') AND name = N'IX_NU_NCL_Calendar_YearOfDate')
BEGIN
    CREATE NONCLUSTERED INDEX [IX_NU_NCL_Calendar_YearOfDate] ON [dbo].[Calendar]
    (
        [YearOfDate] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
    ON [PRIMARY];
END
GO
 
EXEC sp_addextendedproperty N'MS_Description', N'日历数据表', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', NULL, NULL;
GO
EXEC sp_addextendedproperty N'MS_Description', N'日历日期', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'CalendarDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期天数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Days';
GO
EXEC sp_addextendedproperty N'MS_Description', N'周内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfWeek';
GO
EXEC sp_addextendedproperty N'MS_Description', N'工作日标志(1:工作日,0:非工作日)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WorkDayFlag';
GO
EXEC sp_addextendedproperty N'MS_Description', N'旬内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfPeriod';
GO
EXEC sp_addextendedproperty N'MS_Description', N'月内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfMonth';
GO
EXEC sp_addextendedproperty N'MS_Description', N'季内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfQuarter';
GO
EXEC sp_addextendedproperty N'MS_Description', N'年内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfYear';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内日索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'DayOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期周数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Weeks';
GO
EXEC sp_addextendedproperty N'MS_Description', N'旬内周索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WeekOfPeriod';
GO
EXEC sp_addextendedproperty N'MS_Description', N'月内周索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WeekOfMonth';
GO
EXEC sp_addextendedproperty N'MS_Description', N'季内周索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WeekOfQuarter';
GO
EXEC sp_addextendedproperty N'MS_Description', N'年内周索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WeekOfYear';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内周索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'WeekOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期旬数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Periods';
GO
EXEC sp_addextendedproperty N'MS_Description', N'月内旬索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'PeriodOfMonth';
GO
EXEC sp_addextendedproperty N'MS_Description', N'季内旬索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'PeriodOfQuarter';
GO
EXEC sp_addextendedproperty N'MS_Description', N'年内旬索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'PeriodOfYear';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内旬索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'PeriodOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期月数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Months';
GO
EXEC sp_addextendedproperty N'MS_Description', N'季内月索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'MonthOfQuarter';
GO
EXEC sp_addextendedproperty N'MS_Description', N'年内月索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'MonthOfYear';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内月索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'MonthOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期季数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Quarters';
GO
EXEC sp_addextendedproperty N'MS_Description', N'年内季索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'QuarterOfYear';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内季索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'QuarterOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期年数(从0开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'Years';
GO
EXEC sp_addextendedproperty N'MS_Description', N'日期内年索引(从1开始计数)', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'YearOfDate';
GO
EXEC sp_addextendedproperty N'MS_Description', N'标记ID,辅助扩展字段列', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'TagID';
GO
EXEC sp_addextendedproperty N'MS_Description', N'标志ID,辅助扩展字段列', 'SCHEMA', N'dbo', 'TABLE', N'Calendar', 'COLUMN', N'FlagID';
GO
 
日历数据表填充数据
    
初始化日历表数据的功能封装在一个存储过程中,T-SQL代码如下:
IF OBJECT_ID(N'dbo.usp_Calendar_Init', 'P') IS NOT NULL
BEGIN
    DROP PROCEDURE dbo.usp_Calendar_Init;
END
GO
 
--==================================
-- 功能: 初始化日历表中的数据
-- 说明: 具体实现阐述
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
--==================================
CREATE PROCEDURE dbo.usp_Calendar_Init
(
    @dtmEndDate DATETIME,                        -- 日历截止日期时间    
    @chvnErrMsg NVARCHAR(100) OUTPUT            -- 错误消息字符串
)     --$Encode$--
AS
BEGIN
    SET NOCOUNT ON;
 
    SET @chvnErrMsg = N'';
 
    DECLARE @tintReturnValue AS TINYINT;
    SET @tintReturnValue = 1;
 
    IF @dtmEndDate IS NULL
    BEGIN
        SET @chvnErrMsg = N'日历截止日期时间不能为NULL。';
 
        RETURN @tintReturnValue;
    END
 
    DECLARE    @dtmDefaultBasedate AS DATETIME;
    SET @dtmDefaultBasedate = dbo.ufn_GetDefaultBasedate();
 
    IF @dtmDefaultBasedate > @dtmEndDate
    BEGIN
        SET @chvnErrMsg = N'日历截止日期时间不能小于默认基准日期时间【' + CONVERT(VARCHAR(10), @dtmEndDate, 120) + N'】';
 
        RETURN @tintReturnValue;
    END
 
    -- 插入数据
    INSERT INTO dbo.Calendar (
        CalendarDate
        ,Days
        ,DayOfWeek
        ,WorkDayFlag
        ,DayOfPeriod
        ,DayOfMonth
        ,DayOfQuarter
        ,DayOfYear
        ,DayOfDate
        ,Weeks
        ,WeekOfPeriod
        ,WeekOfMonth
        ,WeekOfQuarter
        ,WeekOfYear
        ,WeekOfDate
        ,Periods
        ,PeriodOfMonth
        ,PeriodOfQuarter
        ,PeriodOfYear
        ,PeriodOfDate
        ,Months
        ,MonthOfQuarter
        ,MonthOfYear
        ,MonthOfDate
        ,Quarters
        ,QuarterOfYear
        ,QuarterOfDate
        ,Years
        ,YearOfDate
        ,TagID
        ,FlagID)
    SELECT 
        T.CalendarDate
        ,T.[Days]
        ,T.[DayOfWeek]
        ,CASE WHEN T.[DayOfWeek] >= 6 THEN 0 ELSE 1 END AS WorkDayFlag
        ,T.DayOfPeriod
        ,T.[DayOfMonth]
        ,T.DayOfQuarter
        ,T.[DayOfYear]
        ,T.DayOfDate
        ,T.Weeks
        ,T.WeekOfPeriod
        ,T.WeekOfMonth
        ,T.WeekOfQuarter
        ,T.WeekOfYear
        ,T.WeekOfDate
        ,T.Periods
        ,T.PeriodOfMonth
        ,T.PeriodOfQuarter
        ,T.PeriodOfYear
        ,T.PeriodOfDate
        ,T.Months
        ,T.MonthOfQuarter
        ,T.MonthOfYear
        ,T.MonthOfDate
        ,T.Quarters
        ,T.QuarterOfYear
        ,T.QuarterOfDate
        ,T.Years
        ,T.YearOfDate
        ,0 AS TagID
        ,0 AS FlagID
    FROM (
        SELECT T.CalendarDate
            ,dbo.ufn_Days(T.CalendarDate) AS [Days]
            ,dbo.ufn_DayOfWeek(T.CalendarDate) AS [DayOfWeek]
            ,dbo.ufn_DayOfPeriod(T.CalendarDate) AS DayOfPeriod
            ,dbo.ufn_DayOfMonth(T.CalendarDate) AS [DayOfMonth]
            ,dbo.ufn_DayOfQuarter(T.CalendarDate) AS DayOfQuarter
            ,dbo.ufn_DayOfYear(T.CalendarDate) AS [DayOfYear]
            ,dbo.ufn_DayOfDate(T.CalendarDate) AS DayOfDate
            ,dbo.ufn_Weeks(T.CalendarDate) AS Weeks
            ,dbo.ufn_WeekOfPeriod(T.CalendarDate) AS WeekOfPeriod
            ,dbo.ufn_WeekOfMonth(T.CalendarDate) AS WeekOfMonth
            ,dbo.ufn_WeekOfQuarter(T.CalendarDate) AS WeekOfQuarter
            ,dbo.ufn_WeekOfYear(T.CalendarDate) AS WeekOfYear
            ,dbo.ufn_WeekOfDate(T.CalendarDate) AS WeekOfDate
            ,dbo.ufn_Periods(T.CalendarDate) AS Periods
            ,dbo.ufn_PeriodOfMonth(T.CalendarDate) AS PeriodOfMonth
            ,dbo.ufn_PeriodOfQuarter(T.CalendarDate) AS PeriodOfQuarter
            ,dbo.ufn_PeriodOfYear(T.CalendarDate) AS PeriodOfYear
            ,dbo.ufn_PeriodOfDate(T.CalendarDate) AS PeriodOfDate
            ,dbo.ufn_Months(T.CalendarDate) AS Months
            ,dbo.ufn_MonthOfQuarter(T.CalendarDate) AS MonthOfQuarter
            ,dbo.ufn_MonthOfYear(T.CalendarDate) AS MonthOfYear
            ,dbo.ufn_MonthOfDate(T.CalendarDate) AS MonthOfDate
            ,dbo.ufn_Quarters(T.CalendarDate) AS Quarters
            ,dbo.ufn_QuarterOfYear(T.CalendarDate) AS QuarterOfYear
            ,dbo.ufn_QuarterOfDate(T.CalendarDate) AS QuarterOfDate
            ,dbo.ufn_Years(T.CalendarDate) AS Years
            ,dbo.ufn_YearOfDate(T.CalendarDate) AS YearOfDate
        FROM (
            SELECT DATEADD(DAY, Num, @dtmDefaultBasedate) AS CalendarDate
            FROM dbo.ufn_GetNums(0, DATEDIFF(DAY, @dtmDefaultBasedate, @dtmEndDate))
        ) AS T
    ) AS T
    WHERE NOT EXISTS (SELECT 1 FROM dbo.Calendar WHERE [Days] = T.[Days]);
 
    IF @@ERROR <> 0
    BEGIN
        SET @chvnErrMsg = N'向日历表初始化数据时发生错误。';
 
        RETURN RETURN @tintReturnValue;
    END
 
    SET @tintReturnValue = 0;
 
    RETURN @tintReturnValue;
END
GO
 
-- Test Code
DECLARE 
    @dtmEndDate AS DATETIME,
    @chvnErrMsg NVARCHAR(100),
    @tintReturnValue AS TINYINT;
SELECT
    @dtmEndDate = '1899-12-31',
    @chvnErrMsg = N'',
    @tintReturnValue = 0;
 
EXEC @tintReturnValue = dbo.usp_Calendar_Init
    @dtmEndDate = @dtmEndDate,            -- datetime
    @chvnErrMsg = @chvnErrMsg OUTPUT;    -- nvarchar(100)
 
SELECT
    @chvnErrMsg AS N'Error Message'
    ,@tintReturnValue AS 'Return Value(1:有错误,0:没有错误)';
 
SELECT
    @dtmEndDate = '2099-12-31',
    @chvnErrMsg = N'',
    @tintReturnValue = 0;
 
EXEC @tintReturnValue = dbo.usp_Calendar_Init
    @dtmEndDate = @dtmEndDate,            -- datetime
    @chvnErrMsg = @chvnErrMsg OUTPUT;    -- nvarchar(100)
 
SELECT
    @chvnErrMsg AS N'Error Message'
    ,@tintReturnValue AS 'Return Value(1:有错误,0:没有错误)';
GO
 
以上测试代码的效果,如下图:
 
查询日历数据表中2016年的数据,T-SQL代码如下:
SELECT *
FROM dbo.Calendar
WHERE DAYS BETWEEN dbo.ufn_Days('2016-01-01') AND dbo.ufn_Days('2016-12-31');
GO
 
执行后的查询结果如下图:
 
注意:usp_Calendar_Init存储使用到了数字辅助数字函数dbo.ufn_GetNums,该函数脚本请参考SQL Server数字辅助表的实现
 
总结语
    
    本文断断续续写了两天,才将本系列之前涉及到每个时间粒度有关的内容在本文做个总结。每个时间粒度有关的函数,以及将时间粒度有关的封装在了日历数据表中。
参考清单列表

SQL Server时间粒度系列----第7节日历数据表详解的更多相关文章

  1. SQL Server时间粒度系列----第2节日期、周时间粒度详解

    本文目录列表: 1.从MySQL提供的TO_DAYS和FROM_DAYS这对函数说起2.SQL Server日期时间粒度3.SQL Server周有关时间粒度 4.总结语 5.参考清单列表   从My ...

  2. SQL Server时间粒度系列----第9节时间粒度示例演示

    本文目录列表: 1.准备测试数据 2.向测试数据表添加相关时间粒度字段列 3.基于日月季年统计汇总的演示 4.总结语 5.参考清单列表   准备测试数据   为了提供不同时间粒度示例的演示,就需要测试 ...

  3. SQL Server时间粒度系列

        工作中经常遇到针对业务部门提出不同时间粒度(年.季度.月.周.日等等日期时间粒度,以下简称时间粒度)的数据统计汇总任务,也看到不少博友针对这方便的博文,结合SQL Server的日期时间函数和 ...

  4. SQL Server时间粒度系列----第4节季、年时间粒度详解

    本文目录列表: 1.SQL Server季时间粒度2.SQL Server年时间粒度 3.总结语 4.参考清单列表   SQL Serve季时间粒度       季时间粒度也即是季度时间粒度.一年每3 ...

  5. SQL Server时间粒度系列----第1节时间粒度概述

    本文目录列表: 1.什么是时间粒度?2.SQL Server提供的时间粒度3.SQL Server时间粒度代码演示   4.SQL Server基准日期 5.总结语6.参考清单列表   什么是时间粒度 ...

  6. SQL Server时间粒度系列----第3节旬、月时间粒度详解

    本文目录列表: 1.SQL Server旬时间粒度2.SQL Server月有关时间粒度 3.SQL Server函数重构 4.总结语 5.参考清单列表   SQL Server旬时间粒度       ...

  7. SQL Server时间粒度系列----第8节位运算以及设置日历数据表节假日标志详解

    本文目录列表: 1.位运算 2.设置日历数据表节假日标志 3.总结语 4.参考清单列表   位运算   SQL Server支持的按位运算符有三个,分别为:按位与(&).按位或(|).按位异或 ...

  8. SQL Server时间粒度系列----第5节小时、分钟时间粒度详解

    本文目录列表: 1.SQL Server小时时间粒度2.SQL Server分钟时间粒度 3.总结语 4.参考清单列表   SQL Server小时时间粒度          这里说的时间粒度是指带有 ...

  9. SQL Server时间粒度系列----第6节基于当前日的小时数和分钟数与mysql unix_timestamp和from_unixtime的mssql实现

    本文目录列表: 1.基于当前日的小时数和分钟数2.mysql unix_timestamp和from_unixtime的mssql实现 3.总结语 4.参考清单列表   基于当前日的小时数和分钟数   ...

随机推荐

  1. GIT的认识

    说实话,在听到小伙伴们都说赶紧做作业的时候很茫然,连一点头绪都没有,根本不知道从何入手,但不能因为不会就不去做,于是还是拿起手机,找到小伙伴商量着做着,虽然等的过程很焦急,但还是注册成功了.而开始写对 ...

  2. XCod5 SVN

    近日开始学习IOS开发, 涉及版本管理问题,老大说要使用SVN, 在Windows系统中使用SVN的经验使得俺以为需要首先安装SVN,然后再配置等等, 殊不知XCode5中已经内置了SVN, 在百度一 ...

  3. 事务使用中如何避免误用分布式事务(System.Transactions.TransactionScope)

    1:本地事务DbTransaction和分布式事务TransactionScope的区别: 1.1:System.Data.Common.DbTransaction: 本地事务:这个没什么好说了,就是 ...

  4. Android知识杂记(四)

    1.完整退出activity的设计思路 1.1 封装一个基础activity类 public abstract class RootActivity extends FragmentActivity{ ...

  5. Hadoop学习笔记—11.MapReduce中的排序和分组

    一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出,在Step1.4也就是第四步中,需要对不同分区中的数据进行排 ...

  6. .NET项目版本号的小随笔

    [题外话] 一直以来都对.NET项目中的几个版本号(AssemblyVersion.AssemblyFileVersion.AssemblyInformationalVersion)以及版本号中的Re ...

  7. MySQL 提高Insert性能

    插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例: 连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1x记录大小) 插入索引:(1x索引) 关闭:(1) 这不考虑打开 ...

  8. Windows Azure Storage (23) 计算Azure VHD实际使用容量

    <Windows Azure Platform 系列文章目录> 对于A系列和D系列的虚拟机来说,使用的是普通存储. 普通存储的存储资源,是按照每GB每月计费的.Microsoft Azur ...

  9. Worktile协同特色之一:无处不在的关注

    团队沟通中常见问题 在回答这个问题之前,我们不妨先来思考一下,团队成员之间互相配合沟通的几个问题:1. 任务的执行者在完成这个任务时,如何通知到此任务相关联的其他成员,比如该任务的后续任务执行者?2. ...

  10. Ubuntu安装Python2.7,nodejs

    安装Python2.7 sudo add-apt-repository ppa:fkrull/deadsnakes-python2.7sudo apt-get update sudo apt-get ...