How to check if a string is a legal "dd/mm/yyyy" date?
Asked Answered
P

7

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
Pacifier answered 28/9, 2011 at 11:53 Comment(0)
E
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 ;
}
Everick answered 28/9, 2011 at 12:28 Comment(1)
Generally you're better off converting strings to numbers with the Unary plus operator 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).Pricket
N
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/

Nival answered 28/9, 2011 at 12:0 Comment(5)
It fails when month/day is swaped or given bigger values, cause Date constructor for default increments year in such cases. More here: developer.mozilla.org/pl/…Everick
This is ugly in that it manually splits up a date string (based on culture-specific assumptions); not to mention it requires exception handling.Pabulum
@Pabulum the question states that the date will be in 'dd/mm/yyyy' format. So I thought it was safe to make that assumption.Nival
@ip101: Oops, It seems I mis-recognised the language, sorry. For JS, this is an appropiate solution! Gets my up-vote.Pabulum
lol, how it is, that such bad answer (it fails at least half of given test cases), has most upvotes?Everick
H
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}$/; 
Harlequin answered 28/9, 2011 at 12:21 Comment(3)
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.Pricket
i just gave an example,that this way he can approach not the exact solutionHarlequin
@nnnnnn-you can customize the regex according to your need.Harlequin
P
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.

Pringle answered 28/9, 2011 at 12:52 Comment(0)
S
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.

Sacring answered 28/9, 2011 at 16:25 Comment(0)
E
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.

Everick answered 4/10, 2011 at 6:44 Comment(0)
C
0

for dd/mm/yyyy format only

^(0?[1-9]|[12][0-9]|3[01])[\/](0?[1-9]|1[012])[\/]\d{4}$
Covarrubias answered 17/5, 2017 at 16:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.