SQL Server获取两个日期之间精确的年月日


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*
名称:[dbo].[f_getDateIntervalMulti]
功能:根据2个日期,计算年月日的差值
测试用例:
select [dbo].[f_getDateIntervalMulti] ('2022-01-01','2022-06-30','Y',2)
*/

CREATE FUNCTION [dbo].[f_getDateIntervalMulti] (@d1   AS DATETIME,--开始日期
                                                @d2   AS DATETIME,--结束日期
                                                @type VARCHAR(10),--年月日Y,M,D
                                                @flag INT--保留小数位0,2,4
)
RETURNS NVARCHAR(100)
AS
  BEGIN
      --函数默认@d1 <= @d2,如果@d1 > @d2,则交换
      IF @d1 > @d2
        BEGIN
            DECLARE @d3 AS DATETIME

            SET @d3 = @d1
            SET @d1 = @d2
            SET @d2 = @d3
        END

      DECLARE @yy AS INT,
              @mm AS INT,
              @dd AS INT

      --先直接判断月数,每年的12个月是固定的
      SET @mm = Datediff(MONTH, @d1, @d2)

      --当@d1的日大于@d2+1的日(不到1个月),则月份-1
      IF Day(@d1) > Day(@d2) + 1
        BEGIN
            SET @mm = @mm - 1
        END

      --将@d1日期直接增加已获得的月数,以便后面直接判断天数
      SET @d1 = Dateadd(MONTH, @mm, @d1)
      --根据@mm,获取年数
      SET @yy = @mm / 12
      --根据@mm,将@mm取余数,获取月数
      SET @mm = @mm % 12
      --获取@dd的天数,此时的@d1已经是接近@d2日期了
      SET @dd = Datediff(DAY, @d1, @d2) + 1
      --将@d1日期增加1个月,并减去1天,判断是否与@d2相同(满月判断)
      SET @d1 = Dateadd(MONTH, 1, @d1)
      SET @d1 = Dateadd(DAY, -1, @d1)

      --如果相同,则表示天数进位(满月),日期进位,月份+1
      IF @d1 = @d2
        BEGIN
            SET @mm = @mm + 1
            SET @dd = 0
        END

      --最后也是判断月数是否有进位。判断@mm是否为12(逢12进1),如果是则年份+1,即@yy+1,然后@mm设为0
      IF @mm = 12
        BEGIN
            SET @yy = @yy + 1
            SET @mm = 0
        END

      DECLARE @num DECIMAL(18, 8)
      DECLARE @str AS NVARCHAR(100)

      SET @str=''

      IF @type = 'Y'
        BEGIN
            SET @num=@yy + @mm / 12.0 + @dd / 365.0
        END

      IF @type = 'M'
        BEGIN
            SET @num=@yy * 12 + @mm + @dd / 30.0
        END

      IF @type = 'D'
        BEGIN
            SET @num=@yy * 365 + @mm * 30 + @dd
        END

      IF @flag = 0
        BEGIN
            SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 0), @num))
        END
      ELSE IF @flag = 4
        BEGIN
            SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 4), @num))
        END
      ELSE
        BEGIN
            SET @str=CONVERT(VARCHAR(100), CONVERT(DECIMAL(18, 2), @num))
        END

      RETURN @str
  END

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM