views:

1455

answers:

5

I have a javascript function that checks for a date range. Is there any way to check if a user has input a valid date in a textbox, regardless of format?

function checkEnteredDate() {
            var inputDate = document.getElementById('txtDate');
            //if statement to check for valid date
            var formatDate = new Date(inputDate.value);
            if (formatDate > TodayDate) {
                alert("You cannot select a date later than today.");
                inputDate.value = TodayDate.format("MM/dd/yyyy");
            }
}
+2  A: 

regardless of format?

that will be tricky...

  • 2009/07/02 is a valid date
  • 02/07/09 also
  • 2-7-09 also
  • 02-7-'09 also
  • the second of July 2009 --> also valid
  • twee juli tweeduizend en negen --> also valid (Dutch language)

All valid, but all with a different format. So, regardless of format... I seriously doubt it...

Natrium
+5  A: 

take a look at this library date.js http://code.google.com/p/jqueryjs/source/browse/trunk/plugins/methods/date.js

it has a useful function called fromString which will try and convert a string (based on Date.format) to a valid date object.

the function returns false if it doesn't create a valid date object - you can then try a different format before giving up if all return false.

here are some example formats you could test for:

Date.format = 'dd mmm yyyy';
alert(Date.fromString("26 Jun 2009"));

Date.format = 'mmm dd yyyy';
alert(Date.fromString("Jun 26 2009"));

Date.format = 'dd/mm/yy';
alert(Date.fromString("26/06/09"));

Date.format = 'mm/dd/yy';
alert(Date.fromString("06/26/09"));

Date.format = 'yyyy-mm-dd';
alert(Date.fromString("2009-06-26"));

Josh

Josh
Unless the user specifies the format, you'll still have the europe/US ambiguity problem.
Matt Bridges
@Matt - correct - the only solution for this is to test if the days or months are greater that 12 - if not you have to return that the date is ambiguous and they should use dd/mm/yyyy
Josh
+1  A: 

You can regular expression or a custom made code. Example below:

function isValidDate(dateStr, format) {
   if (format == null) { format = "MDY"; }
   format = format.toUpperCase();
   if (format.length != 3) { format = "MDY"; }
   if ( (format.indexOf("M") == -1) || (format.indexOf("D") == -1) || _
      (format.indexOf("Y") == -1) ) { format = "MDY"; }
   if (format.substring(0, 1) == "Y") { // If the year is first
      var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
      var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/
   } else if (format.substring(1, 2) == "Y") { // If the year is second
      var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/
      var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/
   } else { // The year must be third
      var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/
      var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
   }
   // If it doesn't conform to the right format (with either a 2 digit year or 4 digit year), fail
   if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false) ) { return false; }
   var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
   // Check to see if the 3 parts end up making a valid date
   if (format.substring(0, 1) == "M") { var mm = parts[0]; } else _
      if (format.substring(1, 2) == "M") { var mm = parts[1]; } else { var mm = parts[2]; }
   if (format.substring(0, 1) == "D") { var dd = parts[0]; } else _
      if (format.substring(1, 2) == "D") { var dd = parts[1]; } else { var dd = parts[2]; }
   if (format.substring(0, 1) == "Y") { var yy = parts[0]; } else _
      if (format.substring(1, 2) == "Y") { var yy = parts[1]; } else { var yy = parts[2]; }
   if (parseFloat(yy) <= 50) { yy = (parseFloat(yy) + 2000).toString(); }
   if (parseFloat(yy) <= 99) { yy = (parseFloat(yy) + 1900).toString(); }
   var dt = new Date(parseFloat(yy), parseFloat(mm)-1, parseFloat(dd), 0, 0, 0, 0);
   if (parseFloat(dd) != dt.getDate()) { return false; }
   if (parseFloat(mm)-1 != dt.getMonth()) { return false; }
   return true;
}
Bhaskar
+3  A: 

It is an awfully tricky problem to parse dates in an arbitrary format (as @Natrium points out). It's even more confusing when you consider that europe writes their dates as dd/mm/yyyy, so you can't tell if 2/7/09 is February 7th or July 2nd.

Most people tackle this problem by either using a datepicker type of control from a javascript library, or by using dropdown boxes with set values for month, day, and year.

<select name="month">
<option value="1">January</option>
<option value="2">February</option>
...
<option value="12">December</option>
</select>

<select name="day">
<option value="1">1</option>
<option value="2">2</option>
...
<option value="31">31</option>
</select>

<select name="year">
<option value="2000">2000</option>
<option value="2001">2001</option>
...
<option value="2009">2009</option>
</select>
Matt Bridges
Using selects is an awful solution. Now instead of typing "27" for day, I need to scroll down a whole list of numbers - the pulldown will open into a narrow tall rectangle on most platforms which is difficult to manage. On the other hand, having non-select based controls still subjects you to the parsing problem.
levik
Actually, if you tab to the select field then type "2" then "7" it will correctly pick "27." (Tested using firefox).
Matt Bridges
+1 for a datepicker
jeroen
A: 

I realize I have to get a validation on the code behind. These are all good answers, but was starting to get complicated. I didnt want to back myself in a corner so I choose the alternate route. Thanks