Javascript Date: isLeapYear and getLastDayOfMonth

I recently had to do quite a bit with dates in Javascript, most of which had to do with validating dates a user inserted/selected. Since we don’t use any libraries like jQuery or Prototype, I had to come up with a solution my self. (Which I think is a great motivation not to use libraries in the first place.)

To make my life easier, I extended the Javascript Date object to be able to return useful information about a certain date: whether the year is a leap year or not, and what the last day of a certain month is, taking into account whether a given year is a leap year or not.

Both functions are explained below.

isLeapYear

One of the – what I regard to be – most basic features which is really missing in the default Date object, is the possibility to tell whether a year is a leap year or not. Therefore I wrote the following functions, giving you easy access to this information as if it were a native feature:

// Date functions. (Caveat: months start at 0!)
Date.isLeapYear = function (iYear)
{
	return new Date(iYear, 1, 29).getDate() == 29;
};
Date.prototype.isLeapYear = function ()
{
	return Date.isLeapYear(this.getFullYear());
};

The first method is static which means it is called like any function, given any year as an argument:

for (var iYear = 2007; iYear

which results in:
2007 is not a leap year.
2008 is a leap year.
2009 is not a leap year.
2010 is not a leap year.
2011 is not a leap year.
2012 is a leap year.

The second method is prototyped, enabling you to call it on any Date instance you might already have in your code and without any arguments:

// Create new date instance using the current system date/time.
var oCurrentDate = new Date();
console.log('The current year, ' + oCurrentDate.getFullYear() + ', is'
	+ (oCurrentDate.isLeapYear() ? '' : ' not')
	+ ' a leap year.');

which results in:
The current year, 2012, is a leap year.

getLastDayOfMonth

For my script, I had to automatically fix dates when either the day, month, or year value of a date was changed. To do this I had to figure out what day would be the last day of the current selected month, taking the selected year into account, since February has 29 days if the selected year is a leap year of course.

To calculate the last day of any given month I created two methods:

Date.getLastDayOfMonth = function (iMonth, iYear)
{
	if (/^([024679]|11)$/.test(iMonth))
		return 31;
	if (/^([358]|10)$/.test(iMonth))
		return 30;
	return Date.isLeapYear(iYear) ? 29 : 28;
};
Date.prototype.getLastDayOfMonth = function ()
{
	return Date.getLastDayOfMonth(this.getMonth(), this.getFullYear());
};

The first method is static which means it is called like any function, given any year as an argument:

// Get last day of February 1981.
console.log('The last day of February 1981 is '
	+ Date.getLastDayOfMonth(1, 1981) + '.');

which results in:
The last day of February 1981 is 28.

The second method is prototyped, meaning you can directly call it on any Date instance you already have in your code, and without any arguments:

// Create new date instance using the current system date/time.
var oCurrentDate = new Date();
console.log('The current month\'s last day is '
	+ oCurrentDate.getLastDayOfMonth() + '.');

which results in:
The current month's last day is 30.

The complete script

// Date functions. (Caveat: months start at 0!)
Date.isLeapYear = function (iYear)
{
	return new Date(iYear, 1, 29).getDate() == 29;
};
Date.prototype.isLeapYear = function ()
{
	return Date.isLeapYear(this.getFullYear());
};
 
Date.getLastDayOfMonth = function (iMonth, iYear)
{
	if (/^([024679]|11)$/.test(iMonth))
		return 31;
	if (/^[358]$/.test(iMonth))
		return 30;
	return Date.isLeapYear(iYear) ? 29 : 28;
};
Date.prototype.getLastDayOfMonth = function ()
{
	return Date.getLastDayOfMonth(this.getMonth(), this.getFullYear());
};

It’s a simple script that just really makes dealing with dates a lot easier. Feel free to use it.

2 comments to “Javascript Date: isLeapYear and getLastDayOfMonth”

I think that the second regex in getLastDayOfMonth should read:

/^[358]|10$/

as otherwise my understanding and a little manual testing would both seem to indicate that November isn’t covered.

Thanks for these functions! They’re quite handy.

@Dan: you are absolutely right; I’ve updated the article. Thanks!

Leave a reply