0

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
}
1
  • @VladMinaev - how can I modify this script to produce the required 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` A new script can be used as long as it does with this one does. Commented Apr 9, 2012 at 20:32

1 Answer 1

0

Some points to object:

  • You don't have to check for valid characters, because your match regexp already needs them. If you really want to, use /^[\d\/]*$/.test() instead of that loop.
  • To match dates like 1/1, use /\d{1,2}\/\d{1,2}(\/\d{1,4})?/ as p and just do a num = obj.value.split("/") instead of matching groups
  • To validate the date, have a look at javascript date validation using date object
  • You should also allow ISO date format YYYY-MM-DD, which is parsed natively by Date()
Sign up to request clarification or add additional context in comments.

6 Comments

Those are good points but with the regex as it was, we were seeing characters not being caught. The client wants her team all using the same format - especially since they are supposed to be copying the date from another source and pasting. Their team lead doesn't want them keying in the dates to help reduce the chance of typos (if they were copying and pasting, we wouldn't be seeing the characters appears but I digress).
Uh, to extract dates from another source a c&p web gui is not the best solution I think...
What do you mean with "characters not being caught"?
If someone entered 01/01/a1, an alert would not be thrown and the page would submit. Regarding the C&P, I couldn't agree more but I digress.
OK, then remove the line if (!obj.value.match(p)) return; which stops without an alert, and add an alert in case num == null
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.