I've inherited the following script and it needs to be improved upon some. The function checks that only allowed characters are entered (0123456789/) and then formats a date entered as 1/1/12 will be reformatted as 01/01/2012. This part works just fine after a little tweaking. I now need to take the validation a step further and add the year if it is omitted meaning if a user enters 1/1, it needs to be formatted and have the current year added (e.g. 01/01/2012).
Example of user inputs and required (working) outputs
- a/a/a alert user of error - check
- 1/2/10 updates input field to read as 01/03/2010
- 01/01/12 updates input field to read as 01/01/2012
- 1/10/2 updates input field to read as 01/10/2002
Desired Update (in addition to above) 1/9 updates input field to read as 01/09/2012
Here is the current function (you are welcome to change, rewrite, whatever, as long as the above functionality is retained). jQuery 1.7 library is in use and can be implemented.
function ValidateDate(obj)
{
/************************************************
DESCRIPTION: Validates that a string contains only
valid dates with 2 digit month, 2 digit day,
4 digit year. Date separator has to be /
Uses combination of regular expressions and
string parsing to validate date.
Ex. mm/dd/yyyy
PARAMETERS:
ValidateDate(strValue) - String to be tested for validity
RETURNS:
True if valid, otherwise false.
REMARKS:
Avoids some of the limitations of the Date.parse()
method such as the date separator character.
*************************************************/
var checkOK = "0123456789/";
var checkStr = obj.value;
var allValid = true;
var p = /(\d{1,2})\/(\d{1,2})\/(\d{1,4})/;
var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
// check to see if valid characters were used
for (i = 0; i < checkStr.length; i++)
{
ch = checkStr.charAt(i);
for (j = 0; j < checkOK.length; j++)
if (ch == checkOK.charAt(j))
break;
if (j == checkOK.length)
{
allValid = false;
break;
}
}
if (!allValid)
{
alert("Please use only a combination of " + checkOK + "\'s charaters in the date field. Dates should be entered in the format of mm/dd/yyyy.");
setTimeout((function() { obj.select() }), 0);
return (false);
}
// converts to mm/dd/yyyy format
if (!obj.value.match(p)) return;
num=new Array();
num=obj.value.match(p);
if (num[1].length == 1) num[1]="0" + num[1];
if (num[2].length == 1) num[2]="0" + num[2];
if (num[3].length == 1) num[3]="200" + num[3];
if (num[3].length == 2) num[3]="20" + num[3];
obj.value= num[1] + "/" + num[2] + "/" + num[3];
//check to see if in correct format
if(!objRegExp.test(obj.value))
{
alert('The date entered is not properly formatted.');
return false; //doesn't match pattern, bad date
}
else{
var arrayDate = obj.value.split(RegExp.$1); //split date into month, day, year
var intDay = parseInt(arrayDate[1],10);
var intYear = parseInt(arrayDate[2],10);
var intMonth = parseInt(arrayDate[0],10);
//check for valid month
if(intMonth > 12 || intMonth < 1) {
alert('The date entered is invalid');
return false;
}
//create a lookup for months not equal to Feb.
var arrayLookup = { '01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31,
'08' : 31,'09' : 30,'10' : 31,'11' : 30,'12' : 31}
//check if month value and day value agree
if(arrayLookup[arrayDate[0]] != null) {
if(intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
return true; //found in lookup table, good date
}
//check for February
var booLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
if( ((booLeapYear && intDay <= 29) || (!booLeapYear && intDay <=28)) && intDay !=0)
return true; //Feb. had valid number of days
}
alert(obj.value + ' is not a valid date.');
// return false; //any other values, bad date
}