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
<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>
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 {
public static bool IsLeapYear(int year) { if (year % 100 == 0) { return (year % 400 == 0); } return (year % 4 == 0); } public static bool IsLeapYear(DateTime dt) { return IsLeapYear(dt.Year); }
static void Main(string[] args) { //test the func Console.WriteLine(IsLeapYear(1900).ToString()); Console.WriteLine(IsLeapYear(1994).ToString()); Console.WriteLine(IsLeapYear(1996).ToString()); Console.WriteLine(IsLeapYear(DateTime.Now).ToString()); }
}</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>
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>
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>function isLeapYear(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>
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>
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.
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> 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>
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>
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>leapyear: arg year return (year // 400 = 0 | (year // 100 <> 0 & year // 4 = 0)) </lang> Tricky solution: Check day number of 31st december <lang rexx>leapyear: arg year return date("D",year"1231","S") > 365 </lang>
Ruby
<lang ruby>require 'date' def is_leap_year(year)
Date.new(year).leap?
end</lang>
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>