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