Leap year
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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
ActionScript
<lang actionscript>public function isLeapYear(year:int):Boolean {
if (year % 100 == 0) { return (year % 400 == 0); } return (year % 4 == 0);
}</lang>
Ada
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. <lang Ada>function Is_Leap_Year (Year : in Integer) return Boolean is begin
if Year mod 100 = 0 then return Year mod 400 = 0; else return Year mod 4 = 0; end if;
end Is_Leap_Year;</lang>
ALGOL 68
<lang algol68>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
)</lang> 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
<lang applescript>on leap_year(y) if (y mod 100 is equal to 0) then return (y mod 400 is equal to 0) end if return (y mod 4 is equal to 0) end leap_year
leap_year(1900)</lang>
AutoHotkey
<lang autohotkey>MsgBox % "The year 1600 was " . (IsLeapYear(1600) ? "" : "not ") . "a leap year"
IsLeapYear(Year) {
Return, !Mod(Year, 100) && !Mod(Year, 400) && !Mod(Year, 4)
}</lang>
AutoIt
<lang AutoIt>;AutoIt Version: 3.2.10.0 $Yr=1600 ConsoleWrite ($Yr &" is ") if isLeapYear($Yr) Then
ConsoleWrite ("leap year")
Else
ConsoleWrite ("not leap year")
EndIf
Func isLeapYear($year)
If IsInt($year/100) Then Return IsInt($year/400) EndIf Return IsInt($year/4)
EndFunc</lang>
AWK
<lang AWK>function leapyear( year ) {
if ( year % 100 == 0 ) return ( year % 400 == 0 ) else return ( year % 4 == 0 )
}</lang>
BASIC
Note that the year%
function is not needed for most modern BASICs.
<lang qbasic>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</lang>
BBC BASIC
<lang bbcbasic> 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))</lang>
C /C++
<lang c>#include <stdio.h>
- include <stdbool.h>
bool is_leap_year(int year) {
return !(year%4) && year%100 || !(year%400);
}
int main(){
int test_case[] = {1900, 1994, 1996, 1997, 2000}, key; for(key=0; key<sizeof test_case/sizeof test_case[0]; key++){ int year = test_case[key]; printf("%d is %sa leap year.\n", year, is_leap_year(year)?"":"not "); }
}</lang> 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#
<lang csharp>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 "); } }
}</lang> Sample output: <lang>1900 is not a leap year. 1994 is not a leap year. 1996 is a leap year. 2010 is not a leap year.</lang>
Clojure
<lang clojure>(defn leap-year? [y]
(and (zero? (mod y 4)) (or (pos? (mod y 100)) (zero? (mod y 400)))))</lang>
Common Lisp
<lang lisp> (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))))</lang>
D
<lang d>pure bool leapYear(uint y) {
return (y % 4) == 0 && (y % 100 || (y % 400) == 0);
}</lang>
<lang d>unittest {
int[] good = [1600,1660,1724,1788,1848,1912,1972,2032,2092,2156,2220,2280,2344,2348]; int[] bad = [1698,1699,1700,1750,1800,1810,1900,1901,1973,2100,2107,2200,2203,2289]; assert(equal(filter!(leapYear)(good ~ bad), good));
}</lang>
Delphi
Delphi has standard function IsLeapYear in SysUtils unit.
<lang Delphi>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.</lang>
Ela
<lang ela>let isLeap y | y % 100 == 0 = y % 400 == 0
| else = y % 4 == 0</lang>
Euphoria
<lang euphoria>function isLeapYear(integer year)
return remainder(year,4)=0 and remainder(year,100)!=0 or remainder(year,400)=0
end function</lang>
Forth
<lang forth>: leap-year? ( y -- ? )
dup 400 mod 0= if drop true exit then dup 100 mod 0= if drop false exit then 4 mod 0= ;</lang>
Fortran
<lang fortran>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</lang>
Output:
<lang> F T F T </lang>
GAP
<lang gap>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;</lang>
Go
<lang go>func isLeap(year int) bool {
return year%400 == 0 || year%4 == 0 && year%100 != 0
}</lang>
Groovy
Solution: <lang groovy>(1900..2012).findAll {new GregorianCalendar().isLeapYear(it)}.each {println it}</lang>
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
Haskell
Simple version <lang haskell> 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 </lang> Algorithmic <lang haskell> isleap = foldl1 ((&&).not).flip map [400, 100, 4]. ((0==).).mod </lang> Example using isleap <lang haskell>
- 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 </lang>
Icon and Unicon
Gives leap year status for 2000,1900,2012 and any arguments you give <lang Icon>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 </lang>
J
<lang j>isLeap=: 0 -/@:= 4 100 400 |/ ]</lang>
Example use:
<lang> isLeap 1900 1996 1997 2000 0 1 0 1</lang>
Java
<lang java>new java.util.GregorianCalendar().isLeapYear(year)</lang>
or <lang java>public static boolean isLeapYear(int year){
if(year % 100 == 0) return year % 400 == 0; return year % 4 == 0;
}</lang>
JavaScript
<lang javascript>var isLeapYear = function (year) { return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0); };</lang>
Or, by setting the day to the 29th and checking if the day remains
<lang javascript>// Month values start at 0, so 1 is for February var isLeapYear = function (year) { return new Date(year, 1, 29).getDate() === 29; };</lang>
Liberty BASIC
Simple method
<lang lb>if leap(1996)then
print "leap"
else
print "ordinary"
end if wait
function leap(n)
leap=date$("2/29/";n)
end function</lang>
Calculated method
<lang lb> 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</lang>
Logo
<lang logo>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</lang>
Logtalk
<lang logtalk>leap_year(Year) :-
( mod(Year, 4) =:= 0, mod(Year, 100) =\= 0 -> true ; mod(Year, 400) =:= 0 ).</lang>
Lua
<lang Lua> function isLeapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end </lang>
MATLAB
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. <lang MATLAB>function TrueFalse = isLeapYear(year)
TrueFalse = (eomday(year,2) == 29);
end</lang>
MUMPS
<lang MUMPS>ILY(X) ;IS IT A LEAP YEAR?
QUIT ((X#4=0)&(X#100'=0))!((X#100=0)&(X#400=0))</lang>
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
Objeck
<lang objeck> 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; } }
} </lang>
OCaml
<lang ocaml>let is_leap_year ~year =
if (year mod 100) = 0 then (year mod 400) = 0 else (year mod 4) = 0</lang>
Using Unix Time functions:
<lang ocaml>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)</lang>
OpenEdge/Progress
The DATE function converts month, day, year integers to a date data type and will set the error status if invalid values are passed. <lang progress>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.</lang>
Oz
<lang oz>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</lang>
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
<lang parigp>isLeap(n)={
if(n%400, if(n%100, n%4==0 , 0 ) , 1 )
};</lang>
Alternate version: <lang parigp>isLeap(n)={
if(n%400==0, return(1)); if(n%100==0, return(0)); n%4==0
};</lang>
Perl
<lang Perl>sub leap {
my $yr = $_[0]; if ($yr % 100 == 0) { return ($yr % 400 == 0); } return ($yr % 4 == 0);
}</lang>
Or more concisely:
<lang Perl>sub leap {!($_[0] % 100) ? !($_[0] % 400) : !($_[0] % 4)}</lang>
Using library function/method:
<lang Perl>use Date::Manip; Date_LeapYear($year);
use Date::Manip::Base; my $dmb = new Date::Manip::Base; $dmb->leapyear($year);</lang>
Perl 6
<lang perl6>say "$year is a {Date.is-leap-year($year) ?? 'leap' !! 'common'} year."</lang>
In Rakudo 2010.07, Date.is-leap-year
is implemented as
<lang perl6>multi method is-leap-year($y = $!year) {
$y %% 4 and not $y %% 100 or $y %% 400
}</lang>
PHP
<lang php><?php function isLeapYear(year) {
if (year % 100 == 0) { return (year % 400 == 0); } return (year % 4 == 0);
}</lang>
With date('L')
:
<lang php><?php function isLeapYear(year) {
return (date('L', mktime(0, 0, 0, 2, 1, year)) === '1')
}</lang>
PicoLisp
<lang PicoLisp>(de isLeapYear (Y)
(bool (date Y 2 29)) )</lang>
Output:
: (isLeapYear 2010) -> NIL : (isLeapYear 2008) -> T : (isLeapYear 1600) -> T : (isLeapYear 1700) -> NIL
PL/I
<lang PL/I> 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; </lang>
Overhead of using the date- and time related builtin functions is very significant, they internally call LE routines...
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
<lang postscript>/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</lang>
PowerShell
<lang powershell>function isLeapYear ($year) {
If (([System.Int32]::TryParse($year, [ref]0)) -and ($year -le 9999))
{ $bool = [datetime]::isleapyear($year) } else { throw "Year format invalid. Use only numbers up to 9999." } return $bool }</lang>
Prolog
Works with SWI-Prolog <lang 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). </lang> Output : <lang Prolog> ?- leap_year([1900,1994,1996,1997,2000 ]). leap years : [1996,2000] not leap years : [1900,1994,1997] L = [1900,1994,1996,1997,2000]. </lang>
PureBasic
<lang PureBasic>Procedure isLeapYear(Year)
If (Year%4=0 And Year%100) Or Year%400=0 ProcedureReturn #True Else ProcedureReturn #False EndIf
EndProcedure</lang>
Python
<lang python>import calendar calendar.isleap(year)</lang>
or <lang python>def is_leap_year(year):
if year % 100 == 0: return year % 400 == 0 return year % 4 == 0</lang>
Asking for forgiveness instead of permission:
<lang python>import datetime
def is_leap_year(year):
try: datetime.date(year, 2, 29) except ValueError: return False return True</lang>
R
<lang R>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=""))
}</lang>
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.
REBOL
<lang rebol>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]
] </lang>
Retro
<lang Retro>
: 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 = ;
</lang>
This is provided by the standard calendar library.
REXX
Standard solution: <lang rexx> /*-----------version 1--------------------*/ leapyear: procedure; arg yr return yr//400==0 | (yr//100\==0 & yr//4==0)
/*-----------version 2--------------------*/ leapyear: return arg(1)//400==0 | (arg(1)//100\==0 & arg(1)//4==0) </lang>
Ruby
<lang ruby>require 'date' def is_leap_year(year)
Date.new(year).leap?
end</lang>
Scala
<lang scala>def isLeapYear(year:Int)=if (year%100==0) year%400==0 else year%4==0;
//or use Java's calendar class new java.util.GregorianCalendar().isLeapYear(year)</lang>
Seed7
This function is part of the "time.s7i" library. It returns TRUE if the year is a leap year in the Gregorian calendar.
<lang seed7>const func boolean: isLeapYear (in integer: year) is
return (year rem 4 = 0 and year rem 100 <> 0) or year rem 400 = 0;</lang>
Original source: [1]
SNOBOL4
Predicate leap( ) succeeds/fails, returns nil.
<lang SNOBOL4> 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</lang>
Output:
0: 1066 1: 1492 0: 1900 1: 2000
Tcl
The "classic" modulo comparison <lang tcl>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</lang>
Does Feb 29 exist in the given year? If not a leap year, the clock command will return "03-01" <lang tcl>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</lang>
TUSCRIPT
<lang tuscript> $$ 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 </lang> 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
Yorick
This solution is vectorized and can be applied to scalar or array input. <lang yorick>func is_leap(y) {
return ((y % 4 == 0) & (y % 100 != 0)) | (y % 400 == 0);
}</lang>
Interactive example usage:
> is_leap(1988) 1 > is_leap([1988,1989,1900,2000]) [1,0,0,1]
- Programming Tasks
- Solutions by Programming Task
- ActionScript
- Ada
- ALGOL 68
- AppleScript
- AutoHotkey
- AutoIt
- AWK
- BASIC
- BBC BASIC
- C
- C++
- C sharp
- Clojure
- Common Lisp
- D
- Delphi
- Ela
- Euphoria
- Forth
- Fortran
- GAP
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Liberty BASIC
- Logo
- Logtalk
- Lua
- MATLAB
- MUMPS
- Objeck
- OCaml
- OpenEdge/Progress
- Oz
- PARI/GP
- Perl
- Perl 6
- PHP
- PicoLisp
- PL/I
- PostScript
- PowerShell
- Prolog
- PureBasic
- Python
- R
- REBOL
- Retro
- REXX
- Ruby
- Scala
- Seed7
- SNOBOL4
- Tcl
- TUSCRIPT
- Yorick
- GUISS/Omit
- Date and time