views:

674

answers:

4

I need to do user validation of a date field, it should be in the format yyyyMMdd and should not be more than one year in the future. How would I go about doing this? Currently I only have a crude regexp which is insufficient.

function VerifyDate(source, args)
{
    var regexp = /^([1-2]{1}[0-9]{1})\d{2}([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])$/
    var result = args.Value.match(regexp);     
    if(result) {
        args.IsValid = true;
    } else {
        args.IsValid = false;
    }       
}
+5  A: 

Take the regex to check the format only. You can stay simple:

^(\d{4})(\d{2})(\d{2})$

Then parse the date and check the range:

function VerifyDate(source, args)
{
  args.IsValid = false;
  var regexp = /^(\d{4})(\d{2})(\d{2})$/;
  var daysInMonth = function (y, m) {return 32-new Date(y, m, 32).getDate(); };

  var ma = regexp.exec(args.Value);
  if (ma && ma.length == 4 && ma[2] < 12 && ma[3] <= daysInMonth(ma[1], ma[2]))
  {
    var diff = new Date(ma[1], ma[2], ma[3]) - new Date();
    args.IsValid = diff < 31536000000; // one year = 1000ms*60*60*24*365
  }
}
Tomalak
The code above accepts 20019999 since new Date() do NOT throw an exception in javascript if month>12 or day > daysInMonth(month).
some
Oh. I expected it to. Thanks, I'll factor it in.
Tomalak
Close but still not right... There are at least 2 more bugs: One of them is that all dates in December is considered invalid.
some
A: 

If you are interesting in use a nice js framework to do that, take a look at this link

tanathos
+1  A: 

new Date() don't throw an exception if month or day is out of range. It uses the internal MakeDay to calculate a date (see ECMAScript Language Specification section 15.9.3.1 and 15.9.1.13). To make sure that the date is valid in the function below, the input is converted to integers who is converted to a date, and then the parts of the date are compared to the integers.

Since date uses MakeDay, the calculation of maxDate works even if now is the leep day (xxxx0229 will be yyyy0301 where yyyy=xxxx+1)

function verifyDate(args)
{
    var result=false,
        match = args.Value.match(/^(\d{4})(\d{2})(\d{2})$/);
    if (match && match.length === 4)
    {
        var year = parseInt(match[1],10),
            month =parseInt(match[2],10) -1, // 0 = January
            day = parseInt(match[3],10),
            testDate= new Date(year,month,day),
            now = new Date(),
            maxDate = new Date(now.getFullYear() + 1, now.getMonth(), now. getDate()),
            minDate = new Date(1800,0,1),
            result = (
                 testDate.getFullYear() === year &&
                 testDate.getMonth() === month &&
                 testDate.getDate() === day &&
                 testDate >= minDate &&
                 testDate <= maxDate
            );
   }
   args.IsValue = result;
   return result;   
}
some
A: 

The solution I finally went with is a combination of your answers, I used datejs which seems pretty nice. Here is my final validation function. For some reason the month seems to use a 0 based index so that's why it says -1 in the .set().

function VerifyDate(source, args)
{
    args.IsValid = false;
    var regexp = /^(\d{4})(\d{2})(\d{2})$/;
    var m = regexp.exec(args.Value);
    if (m && m.length == 4) {
     try {
      var result = Date.today().set({ year: Number(m[1]), month: Number(m[2]-1), day: Number(m[3]) });
      if (result < Date.today().add({ years: 1 })) {
       args.IsValid = true;
      }
     }
     catch (ex) {
     }
    }
}
weazl
"Months are identified by an integer in the range 0 to 11, inclusive." see section 15.9.1.4 in http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
some
Btw, I feel like Elisha Gray vs Alexander Graham Bell...
some
Nice, I did not know that before today and hadn't seen the ECMA specification either. But isn't there some javascript reference in a more easily digestable format somewhere? Like a web directory? Digging through a pdf is cumbersome at best.
weazl
The pdf is the authoritative technical resource. A more user friendly resource is http://www.w3schools.com/jsref/default.asp
some