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.

See Also

ActionScript

<lang actionscript>public function isLeapYear(year:int):Boolean {

   if (year % 100 == 0) {
       return (year % 400 == 0);
   }
   return (year % 4 == 0);

}</lang>

ALGOL 68

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

<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>

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>

C/C++

<lang c>#include <stdio.h>

  1. 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>

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;

  1. alternative using built-in function

IsLeapYear := function(n)

 return DaysInYear(n) = 366;

end;</lang>

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>

Icon

Unicon

The Icon solution works in Unicon.

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) {

   if (year % 100 == 0) {
       return (year % 400 == 0);
   }
   return (year % 4 == 0);

}</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>

<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

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>


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>isLeap(n)={

 if(n%400,
   if(n%100,
     n%4==0
   ,
     0
   )
 ,
   1
 )

};</lang>

Alternate version: <lang>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

Works with: Rakudo version 2010.07

<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> declare year picture '9999'; /* 16 August 2010 */ get edit (year) (f(4)); if days(year || '1231', 'YYYYMMDD') - days(year || '0101', 'YYYYMMDD') = 365 then

  put ( year || ' is a leap year');

else

  put (year || ' is not a leap year');

</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>

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>

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>

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]