10

Given a string str, how could I check if it is in the dd/mm/yyyy format and contains a legal date ?

Some examples:

bla bla      // false
14/09/2011   //         true
09/14/2011   // false
14/9/2011    // false
1/09/2011    // false
14/09/11     // false
14.09.2011   // false
14/00/2011   // false
29/02/2011   // false
14/09/9999   //         true
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746

7 Answers7

14

Edit: exact solution below

You could do something like this, but with a more accurate algorithm for day validation:

function testDate(str) {
  var t = str.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  if(t === null)
    return false;
  var d = +t[1], m = +t[2], y = +t[3];

  // Below should be a more acurate algorithm
  if(m >= 1 && m <= 12 && d >= 1 && d <= 31) {
    return true;  
  }

  return false;
}

http://jsfiddle.net/aMWtj/

Date validation alg.: http://www.eee.hiflyers.co.uk/ProgPrac/DateValidation-algorithm.pdf

Exact solution: function that returns a parsed date or null, depending exactly on your requirements.

function parseDate(str) {
  var t = str.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
  if(t !== null){
    var d = +t[1], m = +t[2], y = +t[3];
    var date = new Date(y, m - 1, d);
    if(date.getFullYear() === y && date.getMonth() === m - 1) {
      return date;   
    }
  }

  return null;
}

http://jsfiddle.net/aMWtj/2/

In case you need the function to return true/false and for a yyyy/mm/dd format

function IsValidDate(pText) {
    var isValid = false ;
    var t = pText.match(/^(\d{4})\/(\d{2})\/(\d{2})$/);

    if (t !== null) {
        var y = +t[1], m = +t[2], d = +t[3];
        var date = new Date(y, m - 1, d);

        isValid = (date.getFullYear() === y && date.getMonth() === m - 1) ;
    }

    return isValid ;
}
Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
Adam Jurczyk
  • 2,153
  • 12
  • 16
  • Generally you're better off converting strings to numbers with the [Unary plus operator](https://developer.mozilla.org/en/JavaScript/Reference/Operators/Arithmetic_Operators#.2B_(Unary_Plus)) rather than `parseInt`. I.e., `d=+t[1]`. Avoids problems like where you forgot to include the radix on the day calculation (particularly problematic when we know the day may have leading zeros). – nnnnnn Sep 28 '11 at 12:35
6

Try -

   var strDate = '12/03/2011';
   var dateParts = strDate.split("/");
   var date = new Date(dateParts[2], (dateParts[1] - 1) ,dateParts[0]);

There's more info in this question - Parse DateTime string in JavaScript (the code in my answer is heavily influenced by linked question)

Demo - http://jsfiddle.net/xW2p8/

EDIT

Updated answer, try -

function isValidDate(strDate) {
    if (strDate.length != 10) return false;
    var dateParts = strDate.split("/");
    var date = new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
    if (date.getDate() == dateParts[0] && date.getMonth() == (dateParts[1] - 1) && date.getFullYear() == dateParts[2]) {
        return true;
    }
    else return false;
}

This function passes all the test cases. As far as I'm aware, Adam Jurczyk had posted an accurate answer well before I corrected my original wrong answer. He deserves credit for this.

Demo - http://jsfiddle.net/2r6eX/1/

Community
  • 1
  • 1
ipr101
  • 24,096
  • 8
  • 59
  • 61
  • It fails when month/day is swaped or given bigger values, cause Date constructor for default increments year in such cases. More here: https://developer.mozilla.org/pl/Dokumentacja_j%C4%99zyka_JavaScript_1.5/Obiekty/Date – Adam Jurczyk Sep 28 '11 at 12:33
  • This is ugly in that it manually splits up a date string (based on culture-specific assumptions); not to mention it requires exception handling. – Noldorin Sep 28 '11 at 12:50
  • @Noldorin the question states that the date will be in 'dd/mm/yyyy' format. So I thought it was safe to make that assumption. – ipr101 Sep 28 '11 at 13:02
  • @ip101: Oops, It seems I mis-recognised the language, sorry. For JS, this is an appropiate solution! Gets my up-vote. – Noldorin Sep 28 '11 at 14:05
  • lol, how it is, that such *bad* answer (it fails at least half of given test cases), has most upvotes? – Adam Jurczyk Sep 28 '11 at 14:53
0

for dd/mm/yyyy format only

^(0?[1-9]|[12][0-9]|3[01])[\/](0?[1-9]|1[012])[\/]\d{4}$
0

you can use regular exp to validate date . try like this :

  re = /^\d{1,2}\/\d{1,2}\/\d{4}$/; 
if(form.mydate.value != '' && !form.mydate.value.match(re))
  //do something here

note: this will only work for dd/mm/yyyy

for exact match of your requirement use

 re = /^\d{2}\/\d{2}\/\d{4}$/; 
Pranav
  • 8,563
  • 4
  • 26
  • 42
  • That regular expression is incorrect. The question states that day and month must both be two digits. But aside from that it doesn't work anyway because it doesn't cover maximum days per month or months per year. – nnnnnn Sep 28 '11 at 12:31
  • i just gave an example,that this way he can approach not the exact solution – Pranav Sep 28 '11 at 12:36
  • @nnnnnn-you can customize the regex according to your need. – Pranav Sep 28 '11 at 12:39
0

I'm going to answer a different question, as Misha Moroshko's has already been well-answered: use HTML5. That is, on the assumption that the strings in question arise as user inputs through a Web browser, I propose that the entries be received as

   <input type = "date" ...

I recognize that not all browsers likely to be in use will interpret "date" in a way that rigorously enforces validity. It's the right thing to do, though, will certainly improve as time goes on, and might well be good enough in a particular context even now simply to eliminate the need to validate the date-string after the fact.

NotMe
  • 87,343
  • 27
  • 171
  • 245
Cameron Laird
  • 1,067
  • 5
  • 9
0

Personally, I think the best solution would be to modify the UI to use dropdowns for the month and possibly day selections.

Trying to figure out if 1/2/2001 is January 2nd or February 1st based solely on that input string is impossible.

NotMe
  • 87,343
  • 27
  • 171
  • 245
0

Recent discovery: You can use date.js lib, it adds function Date.parseExact so you can just do Date.parseExact(dateString,"dd/MM/yyyy"). It fails when month is 00, but its still usefull.

Adam Jurczyk
  • 2,153
  • 12
  • 16