2

I'm working in JavaScript and I need to figure out how to determine a valid date using regular expressions.

The matches will be:

dd-mm-yyyy
dd-mm-yy

Also, no leading zeros should be accepted like:

9-8-2010
10-6-99

How can I write a regular expression to do this?

7 Answers 7

5

I came up with this:

function isValidDate(inputDate){

    var myRegex = /^(\d{1,2})([\-\/])(\d{1,2})\2(\d{4}|\d{2})$/;
    var match = myRegex.exec(inputDate);

    if (match != null) {
        var auxDay = match[1];
        var auxMonth = match[3] - 1;
        var auxYear = match[4];
        auxYear = auxYear.length < 3 ? (auxYear < 70 ? '20' + auxYear : '19' + auxYear) : auxYear;
        var testingDate = new Date(auxYear,auxMonth,auxDay);
        return ((auxDay == testingDate.getDate()) && (auxMonth == testingDate.getMonth()) && (auxYear == testingDate.getFullYear()));
    } else return false;
}

Works for dd-mm-yyyy, dd-mm-yy, d-m-yyyy and d-m-yy, using - or / as separators

Based on This script

Sign up to request clarification or add additional context in comments.

Comments

4

You'd better do a split on - and test all elements. But if you really want to use a regex you can try this one :

/^(?:(?:31-(?:(?:0?[13578])|(1[02]))-(19|20)?\d\d)|(?:(?:29|30)-(?:(?:0?[13-9])|(?:1[0-2]))-(?:19|20)?\d\d)|(?:29-0?2-(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))|(?:(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))-(?:(?:0?[1-9])|(?:1[0-2]))-(?:19|20)?\d\d))$/

Explanation:

^            # start of line
 (?:         # group without capture
             # that match 31st of month 1,3,5,7,8,10,12
   (?:       # group without capture
     31      # number 31
     -       # dash
     (?:     # group without capture
       (?:   # group without capture
         0?  # number 0 optionnal
         [13578] # one digit either 1,3,5,7 or 8
       )     # end group
       |     # alternative
       (1[02]) # 1 followed by 0,1 or 2
     )       # end group
     -       # dash
     (19|20)? #numbers 19 or 20 optionnal
     \d\d    # 2 digits from 00 to 99 
   )         # end group
|
   (?:(?:29|30)-(?:(?:0?[13-9])|(?:1[0-2]))-(?:19|20)?\d\d)
|
   (?:29-0?2-(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))
|
   (?:(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))-(?:(?:0?[1-9])|(?:1[0-2]))-(?:19|20)?\d\d)
 )
$

I've explained the first part, leaving the rest as an exercise.

This match one invalid date : 29-02-1900 but is correct for any date between 01-01-1900 and 31-12-2099

Comments

1

To validate yyyy-mm-dd hh:MM simplistically (24 hr time):

var dateFormat=/^20\d{2}-(0[1-9]|1[0-2])-[0-3]\d\s([0-1][0-9]|2[0-3]):[0-5]\d$/;
var myDate="2017-12-31"; 
if ( myDate.match(dateFormat)){
    console.log('matches');
};

Changing the first term ( 20\d{2} ) to \d{4} will allow any 4-digit year, including 0000 and 9999. Also, this regex forces leading zeroes for month, day, hours, and minutes.

This regex checks for:

  • the year to be 20xx; change to your preference.
  • leading zeroes for month, day, hours, and minutes

This regex doesn't check for:

  • Month / day accuracy (it will allow Feb 30 and June 31, for example)
  • Leap years
  • AM or PM (it's for 24-hour time)

Comments

0

Step-by-step solution:

function mDateVerify(date) {
    function isLeap(y) {
        return (y % 400 === 0 || y % 100 !== 0) && (y % 4 === 0);
    }
    date = date.match(/^(\d{1,2})-(\d{1,2})-(\d+)$/);
    if (date === null) {
        return false; // if match failed
    }
    var year = parseInt(date[3], 10),
        month = parseInt(date[2], 10),
        day = parseInt(date[1], 10);
    if (month > 12) {
        return false;
    }
    if (month === 2) { // February
        if (isLeap(year)) {
            if (day > 29) {
                return false;
            }
        } else {
            if (day > 28) {
                return false;
            }
        }
    }
    if ((month < 8 && month % 2 === 0) || (month >= 8 && month % 2 === 1)) {
        if (day > 30) {
            return false;
        }
    }
    if (day > 31) {
        return false;
    }
    return true;
}

Comments

0

I got some result to validate for mm/dd/yyyy format

^(((0[1-9]|1[0-2])/(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])/(29|30)|(0[13578]|1[02])/31)/(?!0000)[0-9]{4}|02/29/([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00))$

Comments

0

This variation validates "ddmmyy" without delimiters.

^(?:(?:(?:0[1-9]|1\d|2[0-8])(?:0[1-9]|1[0-2])|(?:29|30)(?:0[13-9]|1[0-2])|31(?:0[13578]|1[02]))\d{2}|2902((?:0[48]|[2468][048]|[13579][26])|00))$

(was tested on debuggex). ... and it validates leap years by two digits in this century anyway.

Comments

-2

How about this?

[1-9]{1,2}[-./][1-12]{1}[-./](19|20)[1-99]{1}

I have not tested this. And this does not validate leap years

1 Comment

this will allow invalid dates, like 31-02-2010

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.