19

How do I check if a year is a leap year?

I have this code:

declare @year int
set @year = 1968

SELECT CASE WHEN @YEAR = <LEAPYEAR> THEN 'LEAP YEAR' ELSE 'NORMAL YEAR' END

Expected result:

LEAP YEAR
Andriy M
  • 76,112
  • 17
  • 94
  • 154
t-clausen.dk
  • 43,517
  • 12
  • 59
  • 92

8 Answers8

58

Check for 29th Feb:

CASE WHEN ISDATE(CAST(@YEAR AS char(4)) + '0229') = 1 THEN 'LEAP YEAR' ELSE 'NORMAL YEAR' END

or use the following rule

CASE WHEN (@YEAR % 4 = 0 AND @YEAR % 100 <> 0) OR @YEAR % 400 = 0 THEN 'LEAP YEAR'...
Adrian
  • 207
  • 2
  • 13
gbn
  • 422,506
  • 82
  • 585
  • 676
  • 1
    Indeed, the first one is clever; but there's a relatively large hidden computing cost. The second executes significantly faster. Below, I eliminate 2 of the 3 modulus operations, thus eliminating division which is slower than bitwise operations. (See "MOST EFFICIENT LEAP YEAR TEST", infra.) – Kevin P. Rice May 03 '19 at 05:58
10

MOST EFFICIENT LEAP YEAR TEST:

CASE WHEN @YEAR & 3 = 0 AND (@YEAR % 25 <> 0 OR @YEAR & 15 = 0) THEN ...

Adapted from: http://stackoverflow.com/a/11595914/3466415

Kevin P. Rice
  • 5,550
  • 4
  • 33
  • 39
  • Please use this method as it checks on the full year rather than the accepted answer which initially is only check on the leap year day rather than the full year. – LucasM Jan 29 '20 at 16:43
4

Leap year calculation:

(@year % 4 = 0) and (@year % 100 != 0) or (@year % 400 = 0)

When this is true, then it is a leap year. Or to put it in case statement

select case when
    (
        (@year % 4 = 0) and (@year % 100 != 0) or
        (@year % 400 = 0)
    ) then 'LEAP' else 'USUAL' end
;
Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • updated one `AND` the same as you did in your updated answer. I was just testing it in SQL to prove it. So we kinda both answered with the same calculation. – Robert Koritnik Jun 30 '11 at 12:42
3

This could also help

DECLARE @year INT = 2012

SELECT IIF(DAY(EOMONTH(DATEFROMPARTS(@year,2,1))) = 29,1,0)  
Result: 1 --(1 if Leap Year, 0 if not)

SELECT IIF(DAY(EOMONTH(DATEFROMPARTS(@year,2,1))) = 29,'Leap year','Not Leap year')  
Result: Leap year 
Jithin Shaji
  • 5,893
  • 5
  • 25
  • 47
1

Not sure how efficient this is compared to the other solutions. But is another option.

DECLARE @year int = 2016
SELECT CASE 
  WHEN DATEPART(dayofyear, DATEFROMPARTS(@year, 12, 31)) = 366
  THEN 'LEAP' 
  ELSE 'NOT LEAP' 
END
Carlos P.
  • 102
  • 4
1

3 line... but could be also 2...

DECLARE @Y as int = 2021;
DECLARE @Dt as char(10) = CAST(@Y as CHAR(4)) + '-02-29'
SELECT IIF(isDATE(@Dt) = 1, 1,0)

or

DECLARE @Dt as char(10) = '2020-02-29'
SELECT IIF(isDATE(@Dt) = 1, 1,0)

Alen

ACaps
  • 97
  • 1
  • 8
0

I Have a better solution

CREATE FUNCTION dbo.IsLeapYear(@year INT)
RETURNS BIT AS  
     BEGIN
          DECLARE @d DATETIME,
                  @ans BIT      
          SET @d = CONVERT(DATETIME,'31/01/'+CONVERT(VARCHAR(4),@year),103)
          IF DATEPART(DAY,DATEADD(MONTH,1,@d))=29 SET @ans=1 ELSE SET @ans=0
          RETURN @ans
    END
GO

feel free to use

Romesh
  • 2,291
  • 3
  • 24
  • 47
-1

There are different way you can find.

DEMO

DECLARE @year INT = 2024;

-- Date Cast
SELECT @year AS [Year],
    CASE WHEN ISDATE(CAST(@year AS CHAR(4)) + '0229') = 1
        THEN 'Leap Year'
    ELSE 'Not a Leap Year' END

-- Year divisible by 4 but not by 100 OR year divisible by 400
SELECT @year AS [Year],
    CASE WHEN (@year % 4 = 0 AND @year % 100 <> 0) OR (@year % 400 = 0)
        THEN 'Leap Year'
    ELSE 'Not a Leap Year' END

-- Find Month
SELECT @year As [Year],
    CASE WHEN MONTH(DATEADD(D, 1, DATEFROMPARTS(@Year, 2, 28))) <> 3 
        THEN 'Leap Year'
    ELSE 'Not a Leap Year' END

-- A Leap Year has 366 days (the extra day is the 29th of February).
SELECT  @year As [Year],
    CASE WHEN DATEPART(dy,DATEFROMPARTS(@year,12,31)) = 366
        THEN 'Leap Year'
    ELSE 'Not a Leap Year' END
Sender
  • 6,660
  • 12
  • 47
  • 66
  • it seems to me like you just took all the other answers and copied them – t-clausen.dk Jun 06 '22 at 07:21
  • @t-clausen.dk How you feel like that? In my project, I need to find leap year, so I look different option and tested, what is best way to do this. If I look your approach That mean stack overflow all answer is copied from some ware. – Sender Jun 07 '22 at 04:22