如何计算t-sql中两个日期之间的闰年数?

时间:2014-05-23 08:15:36

标签: sql sql-server tsql reporting-services

我在SSRS中做报告,我需要数据集列来计算t-SQL中两个日期之间的闰年数。我找到了单输入参数的函数,无论它是否是闰年,但我的需求是函数中的两个参数或任何t-SQL语句。

谢谢..等待任何人的回复

7 个答案:

答案 0 :(得分:1)

DECLARE @year int
SET @year = 2008
if (((@year % 4 = 0) AND (@year % 100 != 0)) OR (@year % 400 = 0))
print 'Leap year'
ELSE
print 'No'

答案 1 :(得分:1)

目前尚不清楚您想要对第一年和去年做什么取决于您的日期参数。 以下是如何使用递归查询执行此操作的示例:

with cte as
(
     select YEAR('1900-01-01') as [year]
     union all
     select [year] + 1
     from    cte   
     where   [year] + 1 <= YEAR('2100-01-01')
 )
 SELECT COUNT(*)
 FROM cte WHERE
           ([YEAR]%4=0) AND (([YEAR]%100<>0) OR ([YEAR]%400=0))
 OPTION(MAXRECURSION 1000)

SQLFiddle demo

答案 2 :(得分:1)

希望这也有效。

DECLARE @X INT = 1590
DECLARE @Y INT = 1603

DECLARE @COUNT INT = 0,@Z INT = @X

WHILE (@X <= @Y)
BEGIN
    SET @COUNT = @COUNT + 
                (CASE   WHEN (@X%4 = 0 AND @X%100 !=0) OR @X%400 = 0 
                        THEN 1 
                        ELSE 0 END)
    SET @X = @X + 1
END

SELECT @Z BEGIN_YEAR,@Y END_YEAR,@COUNT NO_OF_LEAP_YEARS

结果

enter image description here

答案 3 :(得分:1)

我想,会加上另一个答案。

DECLARE @A DATE = '2008-03-23',
    @B DATE = '2012-04-20'

DECLARE @AM INT,@AY INT,@BM INT,@BY INT
SET @AM = DATEPART(MONTH,@A),   --3
    @AY = DATEPART(YEAR,@A),    --2008
    @BM = DATEPART(MONTH,@B),   --4
    @BY = DATEPART(YEAR,@B)     --2012

DECLARE @COUNT INT = 0

WHILE (@AY <= @BY)
BEGIN
    SET @COUNT = @COUNT + 
                (CASE   WHEN (@AY%4 = 0 AND @AY%100 !=0) OR @AY%400 = 0 
                        THEN 1 
                        ELSE 0 END)
    SET @AY = @AY + 1
END

SET @COUNT = @COUNT + CASE WHEN @AM >= 3 THEN -1 ELSE 0 END

SELECT @A BEGIN_DATE,@Y END_DATE,@COUNT NO_OF_LEAP_YEARS

由于我现在没有可用的sql server实例,所以我没有测试代码。但是你会明白我想要实现的目标。 我宣布@BM,以防你想在结束月份进行检查..

答案 4 :(得分:1)

这里有一个sql函数,基于上面的一些答案应该这样做 -

CREATE FUNCTION [dbo].[LeapDayCount]
(
    @StartDate as datetime,
    @EndDate as datetime
)
RETURNS int as
BEGIN

    DECLARE @StartYear int
    DECLARE @EndYear int
    DECLARE @Year int

    SELECT @StartYear = YEAR(@StartDate)
    SELECT @EndYear = YEAR(@EndDate)

    DECLARE @Count int

    SET @Count = 0

    SET @Year = @StartYear

    WHILE (@Year <= @EndYear)
    BEGIN
        SET @Count = @Count + 
                    (CASE WHEN (@Year%4 = 0 AND @Year%100 !=0) OR @Year%400 = 0 
                            THEN 1 ELSE 0 END)

        SET @Year = @Year + 1
    END

    --remove one leap day if start date is a leap year but after february
    IF ((@StartYear%4 = 0 AND @StartYear%100 !=0) OR @StartYear%400 = 0) AND MONTH(@StartDate) > 2 SET @Count = @Count -1

        --remove one leap day if end date is a leap year but less than 29th Feb
    IF ((@EndYear%4 = 0 AND @EndYear%100 !=0) OR @EndYear%400 = 0) AND (MONTH(@EndDate) = 1 OR (MONTH(@EndDate) = 2 AND DAY(@EndDate) < 29)) SET @Count = @Count -1

RETURN @Count
END

答案 5 :(得分:1)

对原始答案的改进

这有2个改进

  • 修复了一个错误,该错误与在开始日期不是2月的开始日期甚至在2月之后减-1有关
  • 此外,底部的-1函数应检查原始开始月份,而不更改1。
CREATE FUNCTION riskstore.GetLeapYearCount (@Start Date, @End Date)
RETURNS INT
AS
BEGIN
    DECLARE @StartMonth INT = DATEPART(MONTH,@Start)
    DECLARE @StartYear INT = DATEPART(YEAR,@Start)
    DECLARE @OriginalStartYear INT = DATEPART(YEAR,@Start)
    DECLARE @EndMonth INT = DATEPART(MONTH,@End)
    DECLARE @EndYear INT = DATEPART(YEAR,@End)
    DECLARE @COUNT INT = 0
    WHILE (@StartYear <= @EndYear)
    BEGIN
        SET @COUNT = @COUNT + 
                (CASE   WHEN (@StartYear%4 = 0 AND @StartYear%100 !=0) OR @StartYear%400 = 0 
                        THEN 1 
                        ELSE 0 END)
        SET @StartYear = @StartYear + 1
    END
    SET @COUNT = @COUNT + CASE WHEN @StartMonth >= 3 AND ((@OriginalStartYear%4 = 0 AND @OriginalStartYear%100 !=0) OR @OriginalStartYear%400 = 0) THEN -1 ELSE 0 END
    RETURN (@COUNT)
END

答案 6 :(得分:0)

两个日期之间的闰天数。

DECLARE
    @StartDate DATETIME = '2000-02-28',
    @EndDate DATETIME = '2017-02-28'

SELECT ((CONVERT(INT,@EndDate-58)) / 1461 - (CONVERT(INT,@StartDate-58)) / 1461)

-58从1900年3月1日开始计算,/ 1461是29日二月之间的天数。 注意:在Excel中,-58将是-60,因为1900年1月1日在Excel中是第1天,但在SQL中是第0天,SQL不识别1900年2月29日,而Excel确实如此。 另请注意:这个公式每400年就会出错,因为每400年我们都会跳过闰年。 希望这有助于某人。