Checking a date

This script does not work in Netscape 2, Hotjava and WebTV.

No data for Explorer Windows below 6. I'm pretty sure it works in 4-5.5, but not so sure about 3.

On this page I explain how to make sure that a date your users have filled in does in fact exist, and how to check whether it is in the past or in the future.

Example

Try the script. First we check if the date exists. If it does, we check if it lies in the past or in the future.



HTML

This script assumes that your users select their dates from three select boxes, one for the day, one for the month and one for the year. I think entering dates in select boxes is the best possible way. It takes little space, and the user cannot enter complete nonsense, which would be a risk when you'd use normal text fields.

The three select boxes must have similar names, the script counts on it. In the example the name of each select box starts with test_.

<select name="test_day">
	<option>day</option>
	<option value="1">1</option>
	<option value="2">2</option>
	[etc]
</select>
<select name="test_month">
	<option>month</option>
	<option value="1">January</option>
	<option value="2">February</option>
	[etc]
</select>
<select name="test_year">
	<option>year</option>
	<option value="2000">2000</option>
	<option value="2001">2001</option>
	[etc]
</select>

Please note that I start counting months from 1, while in JavaScript January is month 0. I do this because I think the entered date should be human-readable. If that's not necessary for your application, start the values of the options at 0 and change month-1 to month in the script below.

The script

You call the function

var monthLength = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

function checkDate(name)
{
	var x = document.forms[0].elements;
	var day = parseInt(x[name+"_day"].options[x[name+"_day"].selectedIndex].value);
	var month = parseInt(x[name+"_month"].options[x[name+"_month"].selectedIndex].value);
	var year = parseInt(x[name+"_year"].options[x[name+"_year"].selectedIndex].value);

	if (!day || !month || !year)
		return false;

	if (year/4 == parseInt(year/4))
		monthLength[1] = 29;

	if (day > monthLength[month-1])
		return false;

	monthLength[1] = 28;

	var now = new Date();
	now = now.getTime(); //NN3

	var dateToCheck = new Date();
	dateToCheck.setYear(year);
	dateToCheck.setMonth(month-1);
	dateToCheck.setDate(day);
	var checkDate = dateToCheck.getTime();

	var futureDate = (now < checkDate);
	var pastDate = (now > checkDate);

	return [the information you need];
}

Explanation

Before using the function we create an array monthLength in which the lengths of the 12 months are stored. This is to check if the day the user has entered exists in the month the user has entered.

var monthLength = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

Calling the function

When you call this function you should specify a name. This name is the general part of the names of the select boxes. In this example it is test_.
The function returns a boolean, true (date is correct) or false (date is incorrect).

So the call becomes something like:

...[more form validation code]...
var dateExists = checkDate('test');
if (!dateExists)
{
	alert('You have entered an invalid date');
	return false;
}
...[more form validation code]...

The function receives the name you handed to it and starts calculating.

function checkDate(name)
{

Does the date exist?

We read out the values of the selected options in the three select boxes and store them in day, month and year. We make sure that these values are numbers. If they aren't the script can't handle them.

	var x = document.forms[0].elements;
	var day = parseInt(x[name+"_day"].options[x[name+"_day"].selectedIndex].value);
	var month = parseInt(x[name+"_month"].options[x[name+"_month"].selectedIndex].value);
	var year = parseInt(x[name+"_year"].options[x[name+"_year"].selectedIndex].value);

If the user hasn't chosen an option in one or more of the select boxes, you return false because the date is wrong in any case.

	if (!day || !month || !year)
		return false;

Now we're sure the user has actually entered a date. First of all we check for leap years. If the year the user entered is divisble by 4, the year is a leap year and the length of February (month 1 in the array!) should become 29.

	if (year/4 == parseInt(year/4))
		monthLength[1] = 29;

Now check if the day the user entered fits in the month he entered. If it doesn't we return false since the date doesn't exist.

	if (day > monthLength[month-1])
		return false;

Now restore the original 28 to month[1]. This is so that future calls to the script will start with the original value.

	monthLength[1] = 28;

If we made it to here the date exists. If that's all you want to know you can leave out the rest of the function and return true immediately.

Is the date in the past or future?

If you need to know whether the date is in the past or in the future, continue by getting today's date in milliseconds. (Why milliseconds? Because it's easiest to calculate).
See the Introduction to date and time for some more information about the methods we're going to use.
Netscape 3 doesn't support var now = new Date().getTime() so we split it up into two lines.

	var now = new Date();
	now = now.getTime(); //NN3

Then create a Date object with the date the user has filled in and read it out in milliseconds.

	var dateToCheck = new Date();
	dateToCheck.setYear(year);
	dateToCheck.setMonth(month-1);
	dateToCheck.setDate(day);
	var checkDate = dateToCheck.getTime();

Now compare now and checkDate. If the first one is smaller than the second one the entered date is in the future, if it's larger it's in the past.

	var futureDate = (now < checkDate);
	var pastDate = (now > checkDate);

(If the user has checked today's date it's neither in the past nor in the future.)

Now you're ready. You only need to return the information you need.

If you only want to know whether the date exists,

	return true;
}

If you want to know if the date is in the future

	return futureDate;
}

If you're more interested in the past,

	return pastDate;
}