Leap year

From Rosetta Code
Revision as of 01:48, 28 July 2010 by 24.41.5.170 (talk) (added Clojure version)
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.

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.

Clojure

<lang clojure>(defn leap-year? [y]

 (and (zero? (mod y 4)) (or (pos? (mod y 100)) (zero? (mod y 400)))))</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>

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 a NOT leap year."}

    end
 end</lang>

Output:

1900 is a NOT leap year.
1996 is a leap year.
1997 is a NOT 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>

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

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>

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>