Dispersion Design

< Back

Algorithm For Determining If a Year is a Leap Year

2012-04-09

In summary:

It can be determined whether a year is a leap year by the following algorithm:

var isLeapYear = (year % 4) || ((year % 100 === 0) &&
	(year % 400)) ? 0 : 1;

Where the year is the complete year including century (e.g. 2012).

Introduction

It is a little-known fact that not every fourth year is a leap year. Most people only ever need to learn that if a year is divisible by four, then it is a leap year. This, however, is actually a simplification of the leap year rules. Since the Earth orbits the Sun in 365.2425 days, not 365.25 days, additional leap year rules exist to correct for these additional decimal places.

In short, a year is a leap year if it is divisible by four, UNLESS it is also divisible by 100. A year is NOT a leap year if it is divisible by 100 UNLESS it is also divisible by 400.

What this means is that the year 2000, a leap year, was not a leap year simply because 2000 is divisible by four, but because it is also divisible by 400! The year 2100, therefore, will not be a leap year.

ConditionResultExamples
Not divisible by 4Not a leap year2009, 2010, 2011
Divisible by 4Leap year2008, 2012, 2016
Divisible by 100Not a leap year1800, 1900, 2100
Divisible by 400Leap year2000, 2400

Solution

Writing out this algorithm in JavaScript, we get:

var isLeapYear;

if (year % 4 === 0) {
	// Divisible by 4
	if (year % 100 === 0) {
		// Divisible by 100
		if (year % 400 === 0) {
			// Divisible by 400
			isLeapYear = 1;
		} else {
			// Not divisible by 400
			isLeapYear = 0;
		}
	} else {
		// Not divisible by 100
		isLeapYear = 1;
	}
} else {
	// Not divisible by 4
	isLeapYear = 0;
}

All these conditions can be combined into a single boolean statement, simplifying the code and potentially obfuscating the solution:

var isLeapYear;

if ((year % 4) || ((year % 100 === 0) && (year % 400))) {
	isLeapYear = 0;
} else {
	isLeapYear = 1;
}

A ternary conditional operation can then be used to make the solution one single statement:

var isLeapYear = (year % 4) || ((year % 100 === 0) &&
	(year % 400)) ? 0 : 1;

Of course, for most applications, a simple (year % 4) ? 0 : 1 statement would suffice, as it will work correctly for all years between 1901 and 2099. Adding the additional (year % 100) and (year % 400) conditions is a good habit to get into, though, and is essential should you write code that looks at years long past or well into the future.

Other Programming Languages

C, C++ and Java

Very little modification is needed to express the leap year calculation in C, C++ or Java:

int isLeapYear = (year % 4) || ((year % 100 === 0) &&
	(year % 400)) ? 0 : 1;

Perl and PHP

And translating the leap year calculation into PHP or Perl:

$isLeapYear = ($year % 4) || (($year % 100 === 0) &&
	($year % 400)) ? 0 : 1;

Demo