Leap year

From Rosetta Code
Task
Leap year
You are encouraged to solve this task according to the task description, using any language you may know.
Determine whether a given year is a leap year in the Gregorian calendar.

See Also

360 Assembly[edit]

This is a callable subroutine to determine whether or not a given zoned-decimal 4-digit year is a Leap Year. Leap years are "evenly divisible" by 4, except those which end in '00' and are not evenly divisible by 400. The subroutine receives two parameters:

 (1) a 4-digit year (CCYY)
 (2) an 8-byte work area  

The value returned in Register 15 (by convention the "return code") indicates whether the year is a Leap Year:

 When R15 = zero, the year is a leap year. 
 Otherwise it is not.  
 
LPCK CSECT
USING LPCK,15
STM 0,12,20(13) STORE CALLER REGS
LM 1,2,0(1) R1 -> CCYY, R2 -> DOUBLE-WORD WORK AREA
PACK 0(8,2),0(4,1) PACK CCYY INTO WORK AREA
CVB 0,0(2) CONVERT TO BINARY (R0 = CCYY)
SRDL 0,32 R0|R1 = CCYY
LA 2,100 R2 = 100
DR 0,2 DIVIDE BY 100: R0 = YY, R1 = CC
LTR 0,0 YY = 0?
BZ A YES: R0|R1 = CC
SRDL 0,32 NO: R0|R1 = YY
A LA 2,4 R2 = 4
DR 0,2 DIVIDE BY 4: R0 = REMAINDER, R1 = QUOTIENT
LR 15,0 LOAD REMAINDER: IF 0, THEN LEAP YEAR
LM 0,12,20(13) RESTORE REGS
BR 14
END
 

Sample invocation from a COBOL program:

WORKING-STORAGE SECTION. 01 FILLER.

   05 YEAR-VALUE PIC 9(4).
   05 WKAREA PIC X(8).            

PROCEDURE DIVISION.

   MOVE 1936 TO YEAR-VALUE
   CALL 'LPCK' USING YEAR-VALUE, WKAREA
   PERFORM RESULT-DISPLAY
   MOVE 1900 TO YEAR-VALUE
   CALL 'LPCK' USING YEAR-VALUE, WKAREA
   PERFORM RESULT-DISPLAY
   GOBACK.

RESULT-DISPLAY.

   IF RETURN-CODE = ZERO DISPLAY YEAR-VALUE ' IS A LEAP YEAR'
   ELSE DISPLAY YEAR-VALUE ' IS NOT A LEAP YEAR'.

ActionScript[edit]

public function isLeapYear(year:int):Boolean {
if (year % 100 == 0) {
return (year % 400 == 0);
}
return (year % 4 == 0);
}

Ada[edit]

-- Incomplete code, just a sniplet to do the task. Can be used in any package or method.
-- Adjust the type of Year if you use a different one.
function Is_Leap_Year (Year : Integer) return Boolean is
begin
if Year rem 100 = 0 then
return Year rem 400 = 0;
else
return Year rem 4 = 0;
end if;
end Is_Leap_Year;
 
 
-- An enhanced, more efficient version:
-- This version only does the 2 bit comparison (rem 4) if false.
-- It then checks rem 16 (a 4 bit comparison), and only if those are not
-- conclusive, calls rem 100, which is the most expensive operation.
-- I failed to be convinced of the accuracy of the algorithm at first,
-- so I rephrased it below.
-- FYI: 400 is evenly divisible by 16 whereas 100,200 and 300 are not. Ergo, the
-- set of integers evenly divisible by 16 and 100 are all evenly divisible by 400.
-- 1. If a year is not divisible by 4 => not a leap year. Skip other checks.
-- 2. If a year is evenly divisible by 16, it is either evenly divisible by 400 or
-- not evenly divisible by 100 => leap year. Skip further checks.
-- 3. If a year evenly divisible by 100 => not a leap year.
-- 4. Otherwise a leap year.
 
function Is_Leap_Year (Year : Integer) return Boolean is
begin
return (Year rem 4 = 0) and then ((Year rem 16 = 0) or else (Year rem 100 /= 0));
end Is_Leap_Year;
 
 
 
-- To improve speed a bit more, use with
pragma Inline (Is_Leap_Year);

ALGOL 68[edit]

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
MODE YEAR = INT, MONTH = INT, DAY = INT;
 
PROC year days = (YEAR year)DAY: # Ignore 1752 CE for the moment #
( month days(year, 2) = 28 | 365 | 366 );
 
PROC month days = (YEAR year, MONTH month) DAY:
( month | 31,
28 + ABS (year MOD 4 = 0 AND year MOD 100 /= 0 OR year MOD 400 = 0),
31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 
PROC is leap year = (YEAR year)BOOL: year days(year)=366;
 
test:(
[]INT test cases = (1900, 1994, 1996, 1997, 2000);
FOR i TO UPB test cases DO
YEAR year = test cases[i];
printf(($g(0)" is "b("","not ")"a leap year."l$, year, is leap year(year)))
OD
)
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

AppleScript[edit]

on leap_year(y)
return year mod 4 is equal to 0 and (year mod 100 is not equal to 0 or year mod 400 is equal to 0)
end leap_year
 
leap_year(1900)

AutoHotkey[edit]

leapyear(year)
{
if (Mod(year, 100) = 0)
return (Mod(year, 400) = 0)
return (Mod(year, 4) = 0)
}
 
MsgBox, % leapyear(1604)
Output:
Returns 1 if year is a leap year

or

IsLeapYear(Year)
{
return !Mod(Year, 4) && Mod(Year, 100) || !Mod(Year, 400)
}
 
MsgBox % "The year 1604 was " (IsLeapYear(1604) ? "" : "not ") "a leap year"
Output:
The year 1600 was a leap year
The year 1601 was not a leap year
The year 1604 was a leap year

AutoIt[edit]

; AutoIt Version: 3.3.8.1
$Year = 2012
$sNot = " not"
 
If IsLeapYear($Year) Then $sNot = ""
ConsoleWrite ($Year & " is" & $sNot & " a leap year." & @LF)
 
Func IsLeapYear($_year)
Return Not Mod($_year, 4) And (Mod($_year, 100) Or Not Mod($_year, 400))
EndFunc
 
; == But it exists the standard UDF "Date.au3" with this function: "_IsLeapYear($Year)"
 
Output:
2012 is a leap year.

--BugFix (talk) 16:18, 16 November 2013 (UTC)

AWK[edit]

function leapyear( year )
{
if ( year % 100 == 0 )
return ( year % 400 == 0 )
else
return ( year % 4 == 0 )
}


Bash[edit]

#!/bin/bash
year=$(date +"%Y")
if (( $year % 4 == 0 ))
then
if (( $year % 400 == 0 ))
then
echo "This is a leap year"
else
if (( $year % 100 == 0 ))
then
echo "This is not a leap year"
else
echo "This is a leap year"
fi
fi
else
echo "This is not a leap year"
fi
 

BASIC[edit]

Works with: QBasic

Note that the year% function is not needed for most modern BASICs.

DECLARE FUNCTION diy% (y AS INTEGER)
DECLARE FUNCTION isLeapYear% (yr AS INTEGER)
DECLARE FUNCTION year% (date AS STRING)
 
PRINT isLeapYear(year(DATE$))
 
FUNCTION diy% (y AS INTEGER)
IF y MOD 4 THEN
diy = 365
ELSEIF y MOD 100 THEN
diy = 366
ELSEIF y MOD 400 THEN
diy = 365
ELSE
diy = 366
END IF
END FUNCTION
 
FUNCTION isLeapYear% (yr AS INTEGER)
isLeapYear = (366 = diy(yr))
END FUNCTION
 
FUNCTION year% (date AS STRING)
year% = VAL(RIGHT$(date, 4))
END FUNCTION

An old-timey solution:

Works with: Commodore BASIC
10 DEF FNLY(Y)=(Y/4=INT(Y/4))*((Y/100<>INT(Y/100))+(Y/400=INT(Y/400)))

Batch File[edit]

@echo off

::The Main Thing...

for %%x in (1900 2046 2012 1600 1800 2031 1952) do (
call :leap %%x
)
echo.
pause
exit/b
::/The Main Thing...

::The Function...

:leap
set year=%1
set /a op1=%year%%%4
set /a op2=%year%%%100
set /a op3=%year%%%400
if not "%op1%"=="0" (goto :no)
if not "%op2%"=="0" (goto :yes)
if not "%op3%"=="0" (goto :no)
:yes
echo.
echo %year% is a leap year.
goto :EOF
:no
echo.
echo %year% is NOT a leap year.
goto :EOF
::/The Function...
Output:
1900 is NOT a leap year.

2046 is NOT a leap year.

2012 is a leap year.

1600 is a leap year.

1800 is NOT a leap year.

2031 is NOT a leap year.

1952 is a leap year.

Press any key to continue . . .

BBC BASIC[edit]

      REPEAT
INPUT "Enter a year: " year%
IF FNleap(year%) THEN
PRINT ;year% " is a leap year"
ELSE
PRINT ;year% " is not a leap year"
ENDIF
UNTIL FALSE
END
 
DEF FNleap(yr%)
= (yr% MOD 4 = 0) AND ((yr% MOD 400 = 0) OR (yr% MOD 100 <> 0))

Befunge[edit]

Translation of: C
0"2("*:3-:1-:2-:"^"-v<
v*%"d"\!%4::,,"is".:<|
>\45*:*%!+#v_ "ton"vv<
v"ear."+550<,,,,*84<$#
>"y pael a ">:#,_$:#@^
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

Bracmat[edit]

  ( leap-year
=
. mod$(!arg.100):0
& `(mod$(!arg.400):0) { The backtick skips the remainder of the OR operation,
even if the tested condition fails. }
| mod$(!arg.4):0
)
& 1600 1700 1899 1900 2000 2006 2012:?tests
& whl
' ( !tests:%?test ?tests
& ( leap-year$!test&out$(!test " is a leap year")
| out$(!test " is not a leap year")
)
)
& ;
Output:
1600  is a leap year
1700  is not a leap year
1899  is not a leap year
1900  is not a leap year
2000  is a leap year
2006  is not a leap year
2012  is a leap year

C[edit]

#include <stdio.h>
 
int is_leap_year(int year)
{
return (!(year % 4) && year % 100 || !(year % 400)) ? 1 : 0;
}
 
int main()
{
int test_case[] = {1900, 1994, 1996, 1997, 2000}, key, end, year;
for (key = 0, end = sizeof(test_case)/sizeof(test_case[0]); key < end; ++key) {
year = test_case[key];
printf("%d is %sa leap year.\n", year, (is_leap_year(year) == 1 ? "" : "not "));
}
}
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

C++[edit]

Uses C++11. Compile with

g++ -std=c++11 leap_year.cpp
#include <iostream>
 
bool is_leap_year(int year) {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
 
int main() {
for (auto year : {1900, 1994, 1996, 1997, 2000}) {
std::cout << year << (is_leap_year(year) ? " is" : " is not") << " a leap year.\n";
}
}
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

C#[edit]

using System;
 
class Program
{
static void Main()
{
foreach (var year in new[] { 1900, 1994, 1996, DateTime.Now.Year })
{
Console.WriteLine("{0} is {1}a leap year.",
year,
DateTime.IsLeapYear(year) ? string.Empty : "not ");
}
}
}
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
2010 is not a leap year.


Clipper[edit]

Function IsLeapYear( nYear )
Return Iif( nYear%100 == 0, (nYear%400 == 0), (nYear%4 == 0) )

Clojure[edit]

(defn leap-year? [y]
(and (zero? (mod y 4)) (or (pos? (mod y 100)) (zero? (mod y 400)))))

COBOL[edit]

       IDENTIFICATION DIVISION.
PROGRAM-ID. leap-year.
 
DATA DIVISION.
WORKING-STORAGE SECTION.
01 examples VALUE "19001994199619972000".
03 year PIC 9(4) OCCURS 5 TIMES
INDEXED BY year-index.
 
01 remainders.
03 400-rem PIC 9(4).
03 100-rem PIC 9(4).
03 4-rem PIC 9(4).
 
PROCEDURE DIVISION.
PERFORM VARYING year-index FROM 1 BY 1 UNTIL 5 < year-index
MOVE FUNCTION MOD(year (year-index), 400) TO 400-rem
MOVE FUNCTION MOD(year (year-index), 100) TO 100-rem
MOVE FUNCTION MOD(year (year-index), 4) TO 4-rem
 
IF 400-rem = 0 OR ((100-rem NOT = 0) AND 4-rem = 0)
DISPLAY year (year-index) " is a leap year."
ELSE
DISPLAY year (year-index) " is not a leap year."
END-IF
END-PERFORM
 
GOBACK
.

Using Date Intrinsic Functions

 
program-id. leap-yr.
*> Given a year, where 1601 <= year <= 9999
*> Determine if the year is a leap year
data division.
working-storage section.
1 input-year pic 9999.
1 binary.
2 int-date pic 9(8).
2 cal-mo-day pic 9(4).
procedure division.
display "Enter calendar year (1601 thru 9999): "
with no advancing
accept input-year
if input-year >= 1601 and <= 9999
then
*> if the 60th day of a year is Feb 29
*> then the year is a leap year
compute int-date = function integer-of-day
( input-year * 1000 + 60 )
compute cal-mo-day = function mod (
(function date-of-integer ( int-date )) 10000 )
display "Year " input-year space with no advancing
if cal-mo-day = 229
display "is a leap year"
else
display "is NOT a leap year"
end-if
else
display "Input date is not within range"
end-if
stop run
.
end program leap-yr.
 
Output:
Enter calendar year (1601 thru 9999): 2016
Year 2016 is a leap year
Enter calendar year (1601 thru 9999): 2017
Year 2017 is NOT a leap year
Enter calendar year (1601 thru 9999): 2100
Year 2100 is NOT a leap year
Enter calendar year (1601 thru 9999): 2400
Year 2400 is a leap year
Enter calendar year (1601 thru 9999): 3000
Year 3000 is NOT a leap year
Enter calendar year (1601 thru 9999): 4000
Year 4000 is a leap year

Common Lisp[edit]

(defun leap-year-p (year)
(destructuring-bind (fh h f)
(mapcar #'(lambda (n) (zerop (mod year n))) '(400 100 4))
(or fh (and (not h) f))))

Component Pascal[edit]

BlackBox Component Builder

 
MODULE LeapYear;
IMPORT StdLog, Strings, Args;
 
PROCEDURE IsLeapYear(year: INTEGER): BOOLEAN;
BEGIN
IF year MOD 4 # 0 THEN
RETURN FALSE
ELSE
IF year MOD 100 = 0 THEN
IF year MOD 400 = 0 THEN RETURN TRUE ELSE RETURN FALSE END
ELSE
RETURN TRUE
END
END
END IsLeapYear;
 
PROCEDURE Do*;
VAR
p: Args.Params;
year,done,i: INTEGER;
BEGIN
Args.Get(p);
FOR i := 0 TO p.argc - 1 DO
Strings.StringToInt(p.args[i],year,done);
StdLog.Int(year);StdLog.String(":>");StdLog.Bool(IsLeapYear(year));StdLog.Ln
END;
 
END Do;
END LeapYear.
 

Execute: ^Q LeapYear.Do 2000 2004 2013~

Output:
 2000:> $TRUE
 2004:> $TRUE
 2013:> $FALSE

D[edit]

import std.algorithm;
 
bool leapYear(in uint y) pure nothrow {
return (y % 4) == 0 && (y % 100 || (y % 400) == 0);
}
 
void main() {
auto good = [1600, 1660, 1724, 1788, 1848, 1912, 1972, 2032,
2092, 2156, 2220, 2280, 2344, 2348];
auto bad = [1698, 1699, 1700, 1750, 1800, 1810, 1900, 1901,
1973, 2100, 2107, 2200, 2203, 2289];
assert(filter!leapYear(bad ~ good).equal(good));
}


Using the datetime library:

import std.datetime;
 
void main() {
assert(yearIsLeapYear(1724));
assert(!yearIsLeapYear(1973));
assert(!Date(1900, 1, 1).isLeapYear);
assert(DateTime(2000, 1, 1).isLeapYear);
}
 

Delphi/Pascal[edit]

Delphi has standard function IsLeapYear in SysUtils unit.

program TestLeapYear;
 
{$APPTYPE CONSOLE}
 
uses
SysUtils;
 
var
Year: Integer;
 
begin
Write('Enter the year: ');
Readln(Year);
if IsLeapYear(Year) then
Writeln(Year, ' is a Leap year')
else
Writeln(Year, ' is not a Leap year');
Readln;
end.

DWScript[edit]

function IsLeapYear(y : Integer) : Boolean;
begin
Result:= (y mod 4 = 0)
and ( ((y mod 100) <> 0)
or ((y mod 400) = 0) );
end;
 
const good : array [0..13] of Integer =
[1600,1660,1724,1788,1848,1912,1972,2032,2092,2156,2220,2280,2344,2348];
const bad : array [0..13] of Integer =
[1698,1699,1700,1750,1800,1810,1900,1901,1973,2100,2107,2200,2203,2289];
 
var i : Integer;
 
PrintLn('Checking leap years');
for i in good do
if not IsLeapYear(i) then PrintLn(i);
 
PrintLn('Checking non-leap years');
for i in bad do
if IsLeapYear(i) then PrintLn(i);

Ela[edit]

isLeap y | y % 100 == 0 = y % 400 == 0
| else = y % 4 == 0

Elixir[edit]

leap_year? = fn(year) -> :calendar.is_leap_year(year) end
IO.inspect for y <- 2000..2020, leap_year?.(y), do: y
Output:
[2000, 2004, 2008, 2012, 2016, 2020]

Erlang[edit]

 
-module(gregorian).
-export([leap/1]).
 
leap( Year ) -> calendar:is_leap_year( Year ).
 

ERRE[edit]

PROGRAM LEAP_YEAR
 
FUNCTION LEAP(YR%)
LEAP=(YR% MOD 4=0) AND ((YR% MOD 400=0) OR (YR% MOD 100<>0))
END FUNCTION
 
BEGIN
LOOP
INPUT("Enter a year: ",year%)
EXIT IF YEAR%=0
IF LEAP(year%) THEN
PRINT(year%;" is a leap year")
ELSE
PRINT(year%;" is not a leap year")
END IF
END LOOP
END PROGRAM

Euphoria[edit]

function isLeapYear(integer year)
return remainder(year,4)=0 and remainder(year,100)!=0 or remainder(year,400)=0
end function

Excel[edit]

Take two cells, say A1 and B1, in B1 type in :

 
=IF(OR(NOT(MOD(A1,400)),AND(NOT(MOD(A1,4)),MOD(A1,100))),"Leap Year","Not a Leap Year")
 
Output:
1900	Not a Leap Year
1954	Not a Leap Year
1996	Leap Year
2003	Not a Leap Year
2012	Leap Year

F#[edit]

let isLeapYear = System.DateTime.IsLeapYear
assert isLeapYear 1996
assert isLeapYear 2000
assert not (isLeapYear 2001)
assert not (isLeapYear 1900)

Factor[edit]

Call leap-year? word from calendars vocabulary. For example:

USING: calendar prettyprint ;
2011 leap-year? .

Factor uses proleptic Gregorian calendar.

Forth[edit]

: leap-year? ( y -- ? )
dup 400 mod 0= if drop true exit then
dup 100 mod 0= if drop false exit then
4 mod 0= ;

Or more simply (but always computing three "mod"):

: leap-year? dup 4 mod 0= over 16 mod 0= rot 25 mod 0= not or and ;

Fortran[edit]

program leap
implicit none
 
write(*,*) leap_year([1900, 1996, 1997, 2000])
 
contains
 
pure elemental function leap_year(y) result(is_leap)
implicit none
logical :: is_leap
integer,intent(in) :: y
 
is_leap = (mod(y,4)==0 .and. .not. mod(y,100)==0) .or. (mod(y,400)==0)
 
end function leap_year
 
end program leap
Output:
  F T F T 

FreeBASIC[edit]

' version 23-06-2015
' compile with: fbc -s console
 
#Ifndef TRUE ' define true and false for older freebasic versions
#Define FALSE 0
#Define TRUE Not FALSE
#EndIf
 
Function leapyear(Year_ As Integer) As Integer
 
If (Year_ Mod 4) <> 0 Then Return FALSE
If (Year_ Mod 100) = 0 AndAlso (Year_ Mod 400) <> 0 Then Return FALSE
Return TRUE
 
End Function
 
' ------=< MAIN >=------
 
' year is a FreeBASIC keyword
Dim As Integer Year_
 
For Year_ = 1800 To 2900 Step 100
Print Year_; IIf(leapyear(Year_), " is a leap year", " is not a leap year")
Next
 
Print : Print
 
For Year_ = 2012 To 2031
Print Year_;
If leapyear(Year_) = TRUE Then
Print " = leap",
Else
Print " = no",
End If
If year_ Mod 4 = 3 Then Print ' lf/cr
Next
 
' empty keyboard buffer
While InKey <> "" : Var _key_ = InKey : Wend
Print : Print "hit any key to end program"
Sleep
End
Output:
 1800 is not a leap year
 1900 is not a leap year
 2000 is a leap year
 2100 is not a leap year
 2200 is not a leap year
 2300 is not a leap year
 2400 is a leap year
 2500 is not a leap year
 2600 is not a leap year
 2700 is not a leap year
 2800 is a leap year
 2900 is not a leap year

 2012 = leap   2013 = no     2014 = no     2015 = no    
 2016 = leap   2017 = no     2018 = no     2019 = no    
 2020 = leap   2021 = no     2022 = no     2023 = no    
 2024 = leap   2025 = no     2026 = no     2027 = no    
 2028 = leap   2029 = no     2030 = no     2031 = no

FutureBasic[edit]

 
include "ConsoleWindow"
 
// In-line C function to generate random number in range
BeginCFunction
long randomInRange( long min, long max ) {
int i = (arc4random()%(max-min+1))+min;
return (long)i;
}
EndC
toolbox fn randomInRange( long min, long max ) = long
 
// Leap year test function
local fn LeapYear( year as long ) as Boolean
dim as Boolean result : result = _false
 
if year mod 400 == 0 then result = _true  : exit fn
if year mod 100 == 0 then result = _false : exit fn
if year mod 4 == 0 then result = _true  : exit fn
if year mod 4 != 0 then result = _false : exit fn
end fn = result
 
dim as long i, y, knownLeapYear(10)
 
// Array of known leap years from 1980 through 2020 for control
knownLeapYear(0) = 1980 : knownLeapYear(1) = 1984 : knownLeapYear(2) = 1988
knownLeapYear(3) = 1992 : knownLeapYear(4) = 1996 : knownLeapYear(5) = 2000
knownLeapYear(6) = 2004 : knownLeapYear(7) = 2008 : knownLeapYear(8) = 2012
knownLeapYear(9) = 2016 : knownLeapYear(10) = 2020
 
print "Known leap years:"
for i = 0 to 9
if ( fn LeapYear( knownLeapYear(i) ) == _true )
print knownLeapYear(i); " is a leap year."
else
print knownLeapYear(i); " is a not leap year."
end if
next
 
print
 
// Random years from 1980 to 2020 to test
print "Check random years:"
for i = 0 to 20
y = fn randomInRange( 1980, 2020 )
if ( fn LeapYear( y ) == _true )
print y; " is a leap year."
else
print y; " is a not leap year."
end if
next
 

Output (results will vary for random years):

Known leap years:
 1980 is a leap year.
 1984 is a leap year.
 1988 is a leap year.
 1992 is a leap year.
 1996 is a leap year.
 2000 is a leap year.
 2004 is a leap year.
 2008 is a leap year.
 2012 is a leap year.
 2016 is a leap year.

Check random years:
 1998 is a not leap year.
 1987 is a not leap year.
 2015 is a not leap year.
 1998 is a not leap year.
 2020 is a leap year.
 2020 is a leap year.
 2009 is a not leap year.
 2020 is a leap year.
 2018 is a not leap year.
 2013 is a not leap year.
 2003 is a not leap year.
 1994 is a not leap year.
 1989 is a not leap year.
 1999 is a not leap year.
 1984 is a leap year.
 1980 is a leap year.
 1998 is a not leap year.
 2008 is a leap year.
 1983 is a not leap year.
 2007 is a not leap year.
 2004 is a leap year.

GAP[edit]

IsLeapYear := function(n)
return (n mod 4 = 0) and ((n mod 100 <> 0) or (n mod 400 = 0));
end;
 
# alternative using built-in function
IsLeapYear := function(n)
return DaysInYear(n) = 366;
end;

Go[edit]

func isLeap(year int) bool {
return year%400 == 0 || year%4 == 0 && year%100 != 0
}

Groovy[edit]

Solution:

(1900..2012).findAll {new GregorianCalendar().isLeapYear(it)}.each {println it}
Output:
1904
1908
1912
1916
1920
1924
1928
1932
1936
1940
1944
1948
1952
1956
1960
1964
1968
1972
1976
1980
1984
1988
1992
1996
2000
2004
2008
2012

Harbour[edit]

FUNCTION IsLeapYear( nYear )
RETURN iif( nYear % 100 == 0, nYear % 400 == 0, nYear % 4 == 0 )

Haskell[edit]

Simple version

import Data.List
import Control.Monad
import Control.Arrow
 
leaptext x b | b = show x ++ " is a leap year"
| otherwise = show x ++ " is not a leap year"
 
isleapsf j | 0==j`mod`100 = 0 == j`mod`400
| otherwise = 0 == j`mod`4

Algorithmic

isleap = foldl1 ((&&).not).flip map [400, 100, 4]. ((0==).).mod

Example using isleap

*Main> mapM_ (putStrLn. (ap leaptext isleap)) [1900,1994,1996,1997,2000]
1900 is not a leap year
1994 is not a leap year
1996 is a leap year
1997 is not a leap year
2000 is a leap year

TDD version

import Test.HUnit
 
isLeapYear::Int->Bool
isLeapYear y
| mod y 400 == 0 = True
| mod y 100 == 0 = False
| mod y 4 == 0 = True
| otherwise = False
 
tests = TestList[TestCase $ assertEqual "4 is a leap year" True $ isLeapYear 4
,TestCase $ assertEqual "1 is not a leap year" False $ isLeapYear 1
,TestCase $ assertEqual "64 is a leap year" True $ isLeapYear 64
,TestCase $ assertEqual "2000 is a leap year" True $ isLeapYear 2000
,TestCase $ assertEqual "1900 is not a leap year" False $ isLeapYear 1900]

Icon and Unicon[edit]

Gives leap year status for 2000,1900,2012 and any arguments you give

procedure main(arglist)
every y := !([2000,1900,2012]|||arglist) do
write("The year ",y," is ", leapyear(y) | "not ","a leap year.")
end
 
procedure leapyear(year) #: determine if year is leap
if (numeric(year) % 4 = 0 & year % 100 ~= 0) | (numeric(year) % 400 = 0) then return
end

J[edit]

isLeap=: 0 -/@:= 4 100 400 |/ ]

Example use:

   isLeap 1900 1996 1997 2000
0 1 0 1

Java[edit]

By default, java.util.GregorianCalendar switches from Julian calendar to Gregorian calendar at 15 October 1582. The code below uses both the GregorianCalendar class and the algorithm from the wiki. Both values are printed in the output.

import java.util.GregorianCalendar;
import java.text.MessageFormat;
 
public class Leapyear{
public static void main(String[] argv){
int[] yrs = {1800,1900,1994,1998,1999,2000,2001,2004,2100};
GregorianCalendar cal = new GregorianCalendar();
for(int year : yrs){
System.err.println(MessageFormat.format("The year {0,number,#} is leaper: {1} / {2}.",
year, cal.isLeapYear(year), isLeapYear(year)));
}
 
}
public static boolean isLeapYear(int year){
return (year % 100 == 0) ? (year % 400 == 0) : (year % 4 == 0);
}
}
 
 
Output:
The year 1800 is leaper: false / false.
The year 1900 is leaper: false / false.
The year 1994 is leaper: false / false.
The year 1998 is leaper: false / false.
The year 1999 is leaper: false / false.
The year 2000 is leaper: true / true.
The year 2001 is leaper: false / false.
The year 2004 is leaper: true / true.
The year 2100 is leaper: false / false.

JavaScript[edit]

var isLeapYear = function (year) { return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0); };

Or, by setting the day to the 29th and checking if the day remains

// Month values start at 0, so 1 is for February
var isLeapYear = function (year) { return new Date(year, 1, 29).getDate() === 29; };

jq[edit]

Translation of: Julia
def leap:
. as $y | ($y%4) == 0 and ($y < 1582 or ($y%400) == 0 or ($y%100) != 0);

Examples:

def assert(value; f):
value as $value
| ($value|f) | if . then empty else error("assertion violation: \($value) => \(.)") end;
 
((2400, 2012, 2000, 1600, 1500, 1400) | assert(.; leap)),
 
((2100, 2014, 1900, 1800, 1700, 1499) | assert(.; leap|not))
 
Output:
$ jq -n -f Leap_year.jq

Julia[edit]

leap(y) = y%4==0 && (y<1582 || y%400==0 || y%100!=0)
 
# some tests
@assert all([leap(yr) for yr in [2400, 2012, 2000, 1600, 1500, 1400]])
@assert all([~leap(yr) for yr in [2100, 2014, 1900, 1800, 1700, 1499]])

K[edit]

   leapyear:{(+/~x!'4 100 400)!2}
 
a@&leapyear'a:1900,1994,1996,1997,2000
1996 2000

Kotlin[edit]

fun isLeapYear(year: Int) = year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)

Lasso[edit]

define isLeapYear(y::integer) => {
#y % 400 == 0 ? return true
#y % 100 == 0 ? return false
#y % 4 == 0 ? return true
return false
}
 
with test in array(2012,2016,1933,1900,1999,2000) do => {^
isLeapYear(#test)
'\r'
^}
Output:
true
true
false
false
false
true

Liberty BASIC[edit]

Simple method[edit]

if leap(1996)then
print "leap"
else
print "ordinary"
end if
wait
 
function leap(n)
leap=date$("2/29/";n)
end function

Calculated method[edit]

    year = 1908
select case
case year mod 400 = 0
leapYear = 1
case year mod 4 = 0 and year mod 100 <> 0
leapYear = 1
case else
leapYear = 0
end select
if leapYear = 1 then
print year;" is a leap year."
else
print year;" is not a leap year."
end if

LiveCode[edit]

function isLeapYear year
return (year MOD 4 is 0) AND ((year MOD 400 is 0) OR (year MOD 100 is not 0))
end isLeapYear
 
command testLeapYear
set itemDelimiter to comma
put "1900,1994,1996,1997,2000" into years
repeat for each item y in years
put y && "is" && isLeapYear(y) && return after tyears
end repeat
put tyears
end testLeapYear
 
1900 is false
1994 is false
1996 is true
1997 is false
2000 is true

[edit]

to multiple? :n :d
output equal? 0 modulo :n :d
end
to leapyear? :y
output ifelse multiple? :y 100 [multiple? :y 400] [multiple? :y 4]
end

Logtalk[edit]

leap_year(Year) :-
( mod(Year, 4) =:= 0, mod(Year, 100) =\= 0 ->
true
; mod(Year, 400) =:= 0
).

LOLCODE[edit]

BTW  Determine if a Gregorian calendar year is leap
HAI 1.3
HOW IZ I Leap YR Year
BOTH SAEM 0 AN MOD OF Year AN 4
O RLY?
YA RLY
BOTH SAEM 0 AN MOD OF Year AN 100
O RLY?
YA RLY
BOTH SAEM 0 AN MOD OF Year AN 400
O RLY?
YA RLY
FOUND YR WIN
NO WAI
FOUND YR FAIL
OIC
NO WAI
FOUND YR WIN
OIC
NO WAI
FOUND YR FAIL
OIC
IF U SAY SO
 
I HAS A Yearz ITZ A BUKKIT
Yearz HAS A SRS 0 ITZ 1900
Yearz HAS A SRS 1 ITZ 1904
Yearz HAS A SRS 2 ITZ 1994
Yearz HAS A SRS 3 ITZ 1996
Yearz HAS A SRS 4 ITZ 1997
Yearz HAS A SRS 5 ITZ 2000
 
IM IN YR LOOP UPPIN YR Index WILE DIFFRINT Index AN 6
I HAS A YR ITZ Yearz'Z SRS Index
I HAS A NOT
I IZ Leap YR YR MKAY
O RLY?
YA RLY
NOT R ""
NO WAI
NOT R " NOT"
OIC
VISIBLE YR " is" NOT " a leap year"
IM OUTTA YR LOOP
 
KTHXBYE
 
Output:
1900 is NOT a leap year
1904 is a leap year
1994 is NOT a leap year
1996 is a leap year
1997 is NOT a leap year
2000 is a leap year

Lua[edit]

function isLeapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end

Mathematica[edit]

isLeapYear[y_]:= y~Mod~4 == 0 && (y~Mod~100 != 0 || y~Mod~400 == 0)

MATLAB / Octave[edit]

MATLAB, conveniently, provides a function that returns the last day of an arbitrary month of the calendar given the year. Using the fact that February is 29 days long during a leap year, we can write a one-liner that solves this task.

function TrueFalse = isLeapYear(year)
TrueFalse = (eomday(year,2) == 29);
end

Maxima[edit]

leapyearp(year) := is(mod(year, 4) = 0 and
(mod(year, 100) # 0 or mod(year, 400) = 0))$

МК-61/52[edit]

П0	1	0	0	/	{x}	x=0	14	ИП0	4
0 0 ПП 18 ИП0 4 ПП 18 / {x}
x=0 24 1 С/П 0 С/П

Mercury[edit]

:- pred is_leap_year(int::in) is semidet.
 
is_leap_year(Year) :-
( if Year mod 100 = 0 then Year mod 400 = 0 else Year mod 4 = 0 ).

Usage:

:- module leap_year.
:- interface.
 
:- import_module io.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module int, list, string.
 
main(!IO) :-
Years = [1600, 1700, 1899, 1900, 2000, 2006, 2012],
io.write_list(Years, "", write_year_kind, !IO).
 
:- pred write_year_kind(int::in, io::di, io::uo) is det.
 
write_year_kind(Year, !IO) :-
io.format("%d %s a leap year.\n",
[i(Year), s(if is_leap_year(Year) then "is" else "is not" )], !IO).


MIPS Assembly[edit]

Pass year in a0, returns boolean in v0.

 
IsLeap: andi $a1, $a0, 3 #a0 is year to test
bnez $a1 NotLeap
li $a1, 100
div $a0, $a1
mfhi $a1
bnez $a1, Leap
mflo $a1
andi $a1, $a1, 3
bnez $a1, NotLeap
Leap: li $v0, 1
jr $ra
NotLeap:li $v0, 0
jr $ra
 

MUMPS[edit]

ILY(X) ;IS IT A LEAP YEAR?
QUIT ((X#4=0)&(X#100'=0))!((X#100=0)&(X#400=0))
Usage:
USER>W $SELECT($$ILY^ROSETTA(1900):"Yes",1:"No")
No
USER>W $SELECT($$ILY^ROSETTA(2000):"Yes",1:"No")
Yes
USER>W $SELECT($$ILY^ROSETTA(1999):"Yes",1:"No")
No

Nemerle[edit]

Demonstrating implementation as well as use of standard library function.

using System;
using System.Console;
using Nemerle.Assertions;
using Nemerle.Imperative;
 
module LeapYear
{
IsLeapYear(year : int) : bool
requires year >= 1582 otherwise throw ArgumentOutOfRangeException("year must be in Gregorian calendar.")
// without the contract enforcement would work for proleptic Gregorian Calendar
// in that case we might still want to require year > 0
{
when (year % 400 == 0) return true;
when (year % 100 == 0) return false;
when (year % 4 == 0) return true;
false
 
 
}
 
Main() : void
{
WriteLine("2000 is a leap year: {0}", IsLeapYear(2000));
WriteLine("2100 is a leap year: {0}", IsLeapYear(2100));
try {
WriteLine("1500 is a leap year: {0}", IsLeapYear(1500));
}
catch {
|e is ArgumentOutOfRangeException => WriteLine(e.Message)
}
WriteLine("1500 is a leap year: {0}", DateTime.IsLeapYear(1500)); // is false, indicating use of proleptic
// Gregorian calendar rather than reverting to
// Julian calendar
WriteLine("{0} is a leap year: {1}", DateTime.Now.Year,
DateTime.IsLeapYear(DateTime.Now.Year));
}
}
Output:
2000 is a leap year: True
2100 is a leap year: False
Specified argument was out of the range of valid values.
Parameter name: year must be in Gregorian calendar.
1500 is a leap year: False
2013 is a leap year: False

NetRexx[edit]

Demonstrates both a Gregorian/proleptic Gregorian calendar leap-year algorithm and use of the Java library's GregorianCalendar object to determine which years are leap-years.

Note that the Java library indicates that the year 1500 is a leap-year as the Gregorian calendar wasn't established until 1582. The Java library implements the Julian calendar for dates prior to the Gregorian cut-over and leap-year rules in the Julian calendar are different to those for the Gregorian calendar.

/* NetRexx */
 
options replace format comments java crossref savelog symbols nobinary
 
years = '1500 1580 1581 1582 1583 1584 1600 1700 1800 1900 1994 1996 1997 2000 2004 2008 2009 2010 2011 2012 2100 2200 2300 2400 2500 2600'
years['l-a'] = ''
years['n-a'] = ''
years['l-j'] = ''
years['n-j'] = ''
 
loop y_ = 1 to years.words
year = years.word(y_)
if isLeapyear(year) then years['l-a'] = years['l-a'] year
else years['n-a'] = years['n-a'] year
if GregorianCalendar().isLeapYear(year) then years['l-j'] = years['l-j'] year
else years['n-j'] = years['n-j'] year
end y_
 
years['l-a'] = years['l-a'].strip
years['n-a'] = years['n-a'].strip
years['l-j'] = years['l-j'].strip
years['n-j'] = years['n-j'].strip
 
say ' Sample years:' years['all'].changestr(' ', ',')
say ' Leap years (algorithmically):' years['l-a'].changestr(' ', ',')
say ' Leap years (Java library)  :' years['l-j'].changestr(' ', ',')
say ' Non-leap years (algorithmically):' years['n-a'].changestr(' ', ',')
say ' Non-leap years (Java library)  :' years['n-j'].changestr(' ', ',')
 
return
 
-- algorithmically
method isLeapyear(year = int) public constant binary returns boolean
select
when year // 400 = 0 then ly = isTrue
when year // 100 \= 0 & year // 4 = 0 then ly = isTrue
otherwise ly = isFalse
end
return ly
 
method isTrue public constant binary returns boolean
return 1 == 1
 
method isFalse public constant binary returns boolean
return \isTrue
Output:
 Sample years: 1500,1580,1581,1582,1583,1584,1600,1700,1800,1900,1994,1996,1997,2000,2004,2008,2009,2010,2011,2012,2100,2200,2300,2400,2500,2600
     Leap years (algorithmically): 1580,1584,1600,1996,2000,2004,2008,2012,2400
     Leap years (Java library)   : 1500,1580,1584,1600,1996,2000,2004,2008,2012,2400
 Non-leap years (algorithmically): 1500,1581,1582,1583,1700,1800,1900,1994,1997,2009,2010,2011,2100,2200,2300,2500,2600
 Non-leap years (Java library)   : 1581,1582,1583,1700,1800,1900,1994,1997,2009,2010,2011,2100,2200,2300,2500,2600

Nim[edit]

import times
let year = 1980
echo isLeapYear(year)
 
# or
 
proc isLeapYear2(year): bool =
if year mod 100 == 0:
year mod 400 == 0
else: year mod 4 == 0
 
echo isLeapYear2(year)
Output:
true
true

Oberon-2[edit]

 
PROCEDURE IsLeapYear(year: INTEGER): BOOLEAN;
BEGIN
IF year MOD 4 # 0 THEN
RETURN FALSE
ELSE
IF year MOD 100 = 0 THEN
IF year MOD 400 = 0 THEN
RETURN TRUE
ELSE
RETURN FALSE
END
ELSE
RETURN TRUE
END
END
END IsLeapYear;
 

Objeck[edit]

bundle Default {
class LeapYear {
function : Main(args : String[]) ~ Nil {
test_case := [1900, 1994, 1996, 1997, 2000];
each(i : test_case) {
test_case[i]->Print();
if(IsLeapYear(test_case[i])) {
" is a leap year."->PrintLine();
}
else {
" is not a leap year."->PrintLine();
};
};
}
 
function : native : IsLeapYear(year : Int) ~ Bool {
if(year % 4 = 0 & year % 100 <> 0) {
return true;
}
else if(year % 400 = 0) {
return true;
};
 
return false;
}
}
}

OCaml[edit]

let is_leap_year ~year =
if (year mod 100) = 0
then (year mod 400) = 0
else (year mod 4) = 0

Using Unix Time functions:

let is_leap_year ~year =
let tm =
Unix.mktime {
(Unix.gmtime (Unix.time())) with
Unix.tm_year = (year - 1900);
tm_mon = 1 (* feb *);
tm_mday = 29
}
in
(tm.Unix.tm_mday = 29)

Oforth[edit]

Date.IsLeapYear(2000)

ooRexx[edit]

 
::routine isLeapYear
use arg year
d = .datetime~new(year, 1, 1)
return d~isLeapYear
 

OpenEdge/Progress[edit]

The DATE function converts month, day, year integers to a date data type and will set the error status if invalid values are passed.

FUNCTION isLeapYear RETURNS LOGICAL (
i_iyear AS INTEGER
):
 
DATE( 2, 29, i_iyear ) NO-ERROR.
RETURN NOT ERROR-STATUS:ERROR.
 
END FUNCTION. /* isLeapYear */
 
MESSAGE
1900 isLeapYear( 1900 ) SKIP
1994 isLeapYear( 1994 ) SKIP
1996 isLeapYear( 1996 ) SKIP
1997 isLeapYear( 1997 ) SKIP
2000 isLeapYear( 2000 )
VIEW-AS ALERT-BOX.

Oz[edit]

declare
fun {IsLeapYear Year}
case Year mod 100 of 0 then
Year mod 400 == 0
else
Year mod 4 == 0
end
end
in
for Y in [1900 1996 1997 2000] do
if {IsLeapYear Y} then
{System.showInfo Y#" is a leap year."}
else
{System.showInfo Y#" is NOT a leap year."}
end
end
Output:
1900 is NOT a leap year.
1996 is a leap year.
1997 is NOT a leap year.
2000 is a leap year.

PARI/GP[edit]

isLeap(n)={
if(n%400==0, return(1));
if(n%100==0, return(0));
n%4==0
};

Alternate version:

isLeap(n)=!(n%if(n%100,4,400))
Works with: PARI/GP version 2.6.0 and above
isLeap(n)={
if(n%4,0,
n%100,1,
n%400,0,1
)
};

Pascal[edit]

Works with: Free Pascal
program LeapYear;
uses
sysutils;//includes isLeapYear
 
procedure TestYear(y: word);
begin
if IsLeapYear(y) then
writeln(y,' is a leap year')
else
writeln(y,' is NO leap year');
end;
Begin
TestYear(1900);
TestYear(2000);
TestYear(2100);
TestYear(1904);
end.

Output:

1900 is NO leap year
2000 is a leap year
2100 is NO leap year
1904 is a leap year

Perl[edit]

sub isleap {
my $year = shift;
if ($year % 100 == 0) {
return ($year % 400 == 0);
}
return ($year % 4 == 0);
}

Or more concisely:

sub isleap { !($_[0] % 100) ? !($_[0] % 400) : !($_[0] % 4) }

Alternatively, using functions/methods from CPAN modules:

use Date::Manip;
print Date_LeapYear(2000);
 
use Date::Manip::Base;
my $dmb = new Date::Manip::Base;
print $dmb->leapyear(2000);
 
use DateTime;
my $date = DateTime->new(year => 2000);
print $date->is_leap_year();

Perl 6[edit]

Works with: Rakudo version 2010.07
say "$year is a {Date.is-leap-year($year) ?? 'leap' !! 'common'} year."

In Rakudo 2010.07, Date.is-leap-year is implemented as

multi method is-leap-year($y = $!year) {
$y %% 4 and not $y %% 100 or $y %% 400
}

Phix[edit]

Available as an auto-include, implemented as:

global function is_leap_year(integer y)
return remainder(y,4)=0 and (remainder(y,100)!=0 or remainder(y,400)=0)
end function

PHP[edit]

<?php
function isLeapYear($year) {
if ($year % 100 == 0) {
return ($year % 400 == 0);
}
return ($year % 4 == 0);
}

With date('L'):

<?php
function isLeapYear($year) {
return (date('L', mktime(0, 0, 0, 2, 1, $year)) === '1')
}

PicoLisp[edit]

(de isLeapYear (Y)
(bool (date Y 2 29)) )
Output:
: (isLeapYear 2010)
-> NIL

: (isLeapYear 2008)
-> T

: (isLeapYear 1600)
-> T

: (isLeapYear 1700)
-> NIL

PL/I[edit]

dcl mod  builtin;
dcl year fixed bin (31);
 
do year = 1900, 1996 to 2001;
if mod(year, 4) = 0 &
(mod(year, 100) ^= 0 |
mod(year, 400) = 0) then
put skip edit(year, 'is a leap year') (p'9999b', a);
else
put skip edit(year, 'is not a leap year') (p'9999b', a);
end;
Output:
1900 is not a leap year 
1996 is a leap year     
1997 is not a leap year 
1998 is not a leap year 
1999 is not a leap year 
2000 is a leap year     
2001 is not a leap year 

PostScript[edit]

/isleapyear {
dup dup
4 mod 0 eq  % needs to be divisible by 4
exch
100 mod 0 ne  % but not by 100
and
exch
400 mod 0 eq  % or by 400
or
} def

PowerShell[edit]

$Year = 2016
[System.DateTime]::IsLeapYear( $Year )

Prolog[edit]

Works with: SWI-Prolog
leap_year(L) :-
partition(is_leap_year, L, LIn, LOut),
format('leap years : ~w~n', [LIn]),
format('not leap years : ~w~n', [LOut]).
 
is_leap_year(Year) :-
R4 is Year mod 4,
R100 is Year mod 100,
R400 is Year mod 400,
( (R4 = 0, R100 \= 0); R400 = 0).
Output:
 ?- leap_year([1900,1994,1996,1997,2000 ]).
leap years : [1996,2000]
not leap years : [1900,1994,1997]
L = [1900,1994,1996,1997,2000].

There is an handy builtin that simplifies a lot, ending up in a simple query:

 
?- findall(Y, (between(1990,2030,Y),day_of_the_year(date(Y,12,31),366)), L).
L = [1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028].
 

PureBasic[edit]

Procedure isLeapYear(Year)
If (Year%4=0 And Year%100) Or Year%400=0
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure

Python[edit]

import calendar
calendar.isleap(year)

or

def is_leap_year(year):
if year % 100 == 0:
return year % 400 == 0
return year % 4 == 0

Asking for forgiveness instead of permission:

import datetime
 
def is_leap_year(year):
try:
datetime.date(year, 2, 29)
except ValueError:
return False
return True

Scala[edit]

Library: Scala

Ad hoc solution as REPL scripts:

Straightforward[edit]

def isLeapYear(year: Int) = { if (year % 100 == 0) year % 400 == 0 else year % 4 == 0 }

JDK 7 (not recommended)[edit]

new java.util.GregorianCalendar().isLeapYear(year)

JDK 8[edit]

Using JSR-310 java.time.

java.time.LocalDate.ofYearDay(year, 1).isLeapYear()

R[edit]

isLeapYear <- function(year) {
ifelse(year%%100==0, year%%400==0, year%%4==0)
}
 
for (y in c(1900, 1994, 1996, 1997, 2000)) {
print(paste(y, " is ", ifelse(isLeapYear(y), "", "not "), "a leap year.", sep=""))
}
Output:
1900 is not a leap year.
1994 is not a leap year.
1996 is a leap year.
1997 is not a leap year.
2000 is a leap year.

Racket[edit]

(define (leap-year? y)
(and (zero? (modulo y 4)) (or (positive? (modulo y 100)) (zero? (modulo y 400)))))

Raven[edit]

define is_leap_year use $year
$year 100 % 0 = if
$year 400 % 0 =
$year 4 % 0 =

REBOL[edit]

leap-year?: func [
{Returns true if the specified year is a leap year; false otherwise.}
year [date! integer!]
/local div?
][
either date? year [year: year/year] [
if negative? year [throw make error! join [script invalid-arg] year]
]
; The key numbers are 4, 100, and 400, combined as follows:
; 1) If the year is divisible by 4, it’s a leap year.
; 2) But, if the year is also divisible by 100, it’s not a leap year.
; 3) Double but, if the year is also divisible by 400, it is a leap year.
div?: func [n] [zero? year // n]
to logic! any [all [div? 4 not div? 100] div? 400]
]

Retro[edit]

  : isLeapYear? ( y-f )
dup 400 mod 0 = [ drop -1 0 ] [ 1 ] if 0; drop
dup 100 mod 0 = [ drop 0 0 ] [ 1 ] if 0; drop
4 mod 0 = ;

This is provided by the standard calendar library.

REXX[edit]

local variables[edit]

leapyear:  procedure;    parse arg yr
return yr//400==0 | (yr//100\==0 & yr//4==0)

with short-circuit[edit]

The REXX language doesn't support short-circuits, so here is a version that does a short-circuit.

leapyear:  procedure;   parse arg yr
if y//4\==0 then return 0 /*Not ÷ by 4? Not a leap year.*/
return yr//400==0 | yr//100\==0

no local variables[edit]

This version doesn't need a PROCEDURE to hide local variable(s)   [because there aren't any local variables].

leapyear: if arg(1)//4\==0  then return 0
return arg(1)//400==0 | arg(1)//100\==0

handles 2 digit year[edit]

This REXX version has the proviso that if the year is exactly two digits,
the current century is assumed   (i.e.,   no year windowing).

If a year below 100 is to be used, the year should have leading zeroes added (to make it four digits).

leapyear:  procedure;  parse arg y          /*year could be: Y, YY, YYY, YYYY*/
if y//4\==0 then return 0 /*Not ÷ by 4? Not a leap year.*/
if length(y)==2 then y=left(date('S'),2)y /*adjust for a 2─digit YY year.*/
return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */
* * * End of File * * *

Ring[edit]

 
give year
leap = isLeapYear(year)
if leap true see year + " is leap year."
else see year + " is not leap year." ok
 
Func isLeapYear year
if (year % 400) = 0 return true
but (year % 100) = 0 return false
but (year % 4) = 0 return true
else return false ok
 

Ruby[edit]

require 'date'
def leap_year?(year)
Date.new(year).leap?
end

By default, Date switches from Julian calendar to Gregorian calendar at 1582 October 15, the day of calendar reform in Italy and Catholic countries. With Julian calendar, 1500 and 1400 are leap years.

[2000, 1900, 1800, 1700, 1600, 1500, 1400].each do |year|
print year, (leap_year? year) ? " is" : " is not", " a leap year.\n"
end
2000 is a leap year.
1900 is not a leap year.
1800 is not a leap year.
1700 is not a leap year.
1600 is a leap year.
1500 is a leap year.
1400 is a leap year.

To use proleptic Gregorian calendar, a program must pass Date::GREGORIAN.

require 'date'
def leap_year?(year)
Date.new(year, 1, 1, Date::GREGORIAN).leap?
end

With proleptic Gregorian calendar, 1500 and 1400 are not leap years.

2000 is a leap year.
1900 is not a leap year.
1800 is not a leap year.
1700 is not a leap year.
1600 is a leap year.
1500 is not a leap year.
1400 is not a leap year.

Run BASIC[edit]

if date$("02/29/" + mid$(date$("mm/dd/yyyy"),7,4)) then print "leap year" else print "not"

Rust[edit]

fn is_leap(year: i32) -> bool {
let factor = |x| year % x == 0;
factor(4) && (!factor(100) || factor(400))
}
}

Scala[edit]

By default, java.util.GregorianCalendar switches from Julian calendar to Gregorian calendar at 15 October 1582.

//use Java's calendar class
new java.util.GregorianCalendar().isLeapYear(year)

For proleptic Gregorian calendar:

def isLeapYear(year:Int)=if (year%100==0) year%400==0 else year%4==0;
 
//or use Java's calendar class
def isLeapYear(year:Int):Boolean = {
val c = new java.util.GregorianCalendar
c.setGregorianChange(new java.util.Date(Long.MinValue))
c.isLeapYear(year)
}

Scheme[edit]

(define (leap-year? n)
(apply (lambda (a b c) (or a (and (not b) c)))
(map (lambda (m) (zero? (remainder n m)))
'(400 100 4))))

Seed7[edit]

This function is part of the "time.s7i" library. It returns TRUE if the year is a leap year in the Gregorian calendar.

const func boolean: isLeapYear (in integer: year) is
return (year rem 4 = 0 and year rem 100 <> 0) or year rem 400 = 0;

Original source: [1]

Sidef[edit]

func isleap(year) {
if (year %% 100) {
return (year %% 400);
}
return (year %% 4);
}

or a little bit simpler:

func isleap(year) { year %% 100 ? (year %% 400) : (year %% 4) };

Smalltalk[edit]

Smalltalk has a built-in method named isLeapYear:

 
Date today isLeapYear.
 

SNOBOL4[edit]

Predicate leap( ) succeeds/fails, returns nil.

        define('leap(yr)')  :(end_leap)
leap eq(remdr(yr,400),0) :s(return)
eq(remdr(yr,100),0) :s(freturn)
eq(remdr(yr,4),0)  :s(return)f(freturn)
end_leap
 
* # Test and display (with ?: kluge)
test = "output = ('10' ? (*leap(yr) 1 | 0)) ': ' yr"
yr = '1066'; eval(test)
yr = '1492'; eval(test)
yr = '1900'; eval(test)
yr = '2000'; eval(test)
end
Output:
0: 1066
1: 1492
0: 1900
1: 2000

Swift[edit]

func isLeapYear(year:Int) -> Bool {
return (year % 100 == 0) ? (year % 400 == 0) : (year % 4 == 0)
}
 
println(isLeapYear(2000))
println(isLeapYear(2011))
Output:
true
false

Tcl[edit]

The "classic" modulo comparison:

proc isleap1 {year} {
return [expr {($year % 4 == 0) && (($year % 100 != 0) || ($year % 400 == 0))}]
}
isleap1 1988 ;# => 1
isleap1 1989 ;# => 0
isleap1 1900 ;# => 0
isleap1 2000 ;# => 1

Does Feb 29 exist in the given year? If not a leap year, the clock command will return "03-01". (This code will switch to the Julian calendar for years before 1582.)

proc isleap2 year {
return [expr {[clock format [clock scan "$year-02-29" -format "%Y-%m-%d"] -format "%m-%d"] eq "02-29"}]
}
isleap2 1988 ;# => 1
isleap2 1989 ;# => 0
isleap2 1900 ;# => 0
isleap2 2000 ;# => 1

TUSCRIPT[edit]

$$ MODE TUSCRIPT
LOOP year="1900'1994'1996'1997'2000",txt=""
SET dayoftheweek=DATE(number,29,2,year,number)
IF (dayoftheweek==0) SET txt="not "
PRINT year," is ",txt,"a leap year"
ENDLOOP
Output:
1900 is not a leap year
1994 is not a leap year
1996 is a leap year
1997 is not a leap year
2000 is a leap year 

UNIX Shell[edit]

Original Bourne:

leap() {
if expr $1 % 4 >/dev/null; then return 1; fi
if expr $1 % 100 >/dev/null; then return 0; fi
if expr $1 % 400 >/dev/null; then return 1; fi
return 0;
}

Using GNU date(1):

leap() {
date -d "$1-02-29" >/dev/null 2>&1;
}

Defining a bash function is_leap which accepts a YEAR argument, and uses no IO redirection, nor any extra processes.

is_leap() {
local year=$(( 10#${1:?'Missing year'} ))
(( year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ) )) && return 0
return 1
}

Using the cal command: (note that this invokes two processes with IO piped between them and is relatively heavyweight compared to the above shell functions: leap and is_leap)

leap() {
cal 02 $1 | grep -q 29
}
 

Ursa[edit]

This program takes a year as a command line argument.

decl int year
set year (int args<1>)
if (= (mod year 4) 0)
if (and (= (mod year 100) 0) (not (= (mod year 400) 0)))
out year " is not a leap year" endl console
else
out year " is a leap year" endl console
end if
else
out year " is not a leap year" endl console
end if

Output in Bash:

$ ursa leapyear.u 1900
1900 is not a leap year
$ ursa leapyear.u 2000
2000 is a leap year

Vala[edit]

void main() {
DateYear[] years = {1900, 1994, 1996, 1997, 2000};
foreach (DateYear year in years) {
string status = year.is_leap_year() ? "" : "not ";
print("%d is %sa leap year.\n", (int) year, status);
}
}

VBScript[edit]

 
Function IsLeapYear(yr)
IsLeapYear = False
If yr Mod 4 = 0 And (yr Mod 400 = 0 Or yr Mod 100 <> 0) Then
IsLeapYear = True
End If
End Function
 
'Testing the function.
arr_yr = Array(1900,1972,1997,2000,2001,2004)
 
For Each yr In arr_yr
If IsLeapYear(yr) Then
WScript.StdOut.WriteLine yr & " is leap year."
Else
WScript.StdOut.WriteLine yr & " is NOT leap year."
End If
Next
 
Output:
1900 is NOT leap year.
1972 is leap year.
1997 is NOT leap year.
2000 is leap year.
2001 is NOT leap year.
2004 is leap year.

Vedit macro language[edit]

while (#1 = Get_Num("Year: ")) {
#2 = (#1 % 4 == 0) && ((#1 % 100 != 0) || (#1 % 400 == 0))
if (#2) {
Message(" is leap year\n")
} else {
Message(" is not leap year\n")
}
}

The following version requires Vedit 6.10 or later:

while (#1 = Get_Num("Year: ")) {
if (Is_Leap_Year(#1)) {
Message(" is leap year\n")
} else {
Message(" is not leap year\n")
}
}

Wortel[edit]

@let {
isLeapYear !?{\~%%1H \~%%4H \~%%4}
 !-isLeapYear @range[1900 2000]
}

Returns:

[1904 1908 1912 1916 1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000]

X86 Assembly[edit]

Using FASM syntax. Leaf function fits nicely into your program.

    align 16
; Input year as signed dword in EAX
IsLeapYear:
test eax,11b
jz .4
retn ; 75% : ZF=0, not a leap year
.4:
mov ecx,100
cdq
idiv ecx
test edx,edx
jz .100
cmp edx,edx
retn ; 24% : ZF=1, leap year
.100:
test eax,11b
retn ; 1% : ZF=?, leap year if EAX%400=0

XLISP[edit]

(DEFUN LEAP-YEARP (YEAR)
(AND (= (MOD YEAR 4) 0) (OR (/= (MOD YEAR 100) 0) (= (MOD YEAR 400) 0))))
 
; Test the function
(DISPLAY (MAPCAR LEAP-YEARP '(1600 1640 1800 1928 1979 1990 2000 2004 2005 2016)))
Output:
(#T #T () #T () () #T #T () #T)

XPL0[edit]

func LeapYear(Y);       \Return 'true' if Y is a leap year
int Y;
[if rem(Y/100)=0 then return rem(Y/400)=0;
return rem(Y/4)=0;
];

Yorick[edit]

This solution is vectorized and can be applied to scalar or array input.

func is_leap(y) {
return ((y % 4 == 0) & (y % 100 != 0)) | (y % 400 == 0);
}

Interactive example usage:

> is_leap(1988)
1
> is_leap([1988,1989,1900,2000])
[1,0,0,1]

zkl[edit]

Time.Date.isLeapYear(1988) //-->True
T(1988,1989,1900,2000).apply(Time.Date.isLeapYear)
//-->L(True,False,False,True)