Javascript date regex DD/MM/YYYY

I know there are a lot of regex threads out there by I need a specific pattern I couldn't fin anywhere

This regex validates in a YYYY-MM-DD format

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

I need the pattern to be DD/MM/YYYY (day first since it's in spanish and only "/", "-" should not be allowed)

I searched several regex libraries and I think this one should work... but since I'm not familiar with regex I'm not sure it validates like that

(0[1-9]|[12][0-9]|3[01])[ \.-](0[1-9]|1[012])[ \.-](19|20|)\d\d

I also don't know ho to escape the slashes, I try to "see" the logic in the string but it's like trying "see" the Matrix code for me. I'm placing the regex string in a options .js

[...]  },
"date": {
                    "regex": (0[1-9]|[12][0-9]|3[01])[ \.-](0[1-9]|1[012])[ \.-](19|20|)\d\d,
                    "alertText": "Alert text AAAA-MM-DD"
                },
"other type..."[...]

So, if the regex is ok, how would I escape it? if it's not, what's the correct regex and how do I escape it? :P

Thanks a lot


Solution 1:

You could take the regex that validates YYYY/MM/DD and flip it around to get what you need for DD/MM/YYYY:

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

BTW - this regex validates for either DD/MM/YYYY or DD-MM-YYYY

P.S. This will allow dates such as 31/02/4899

Solution 2:

A regex is good for matching the general format but I think you should move parsing to the Date class, e.g.:

function parseDate(str) {
  var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
  return (m) ? new Date(m[3], m[2]-1, m[1]) : null;
}

Now you can use this function to check for valid dates; however, if you need to actually validate without rolling (e.g. "31/2/2010" doesn't automatically roll to "3/3/2010") then you've got another problem.

[Edit] If you also want to validate without rolling then you could add a check to compare against the original string to make sure it is the same date:

function parseDate(str) {
  var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
    , d = (m) ? new Date(m[3], m[2]-1, m[1]) : null
    , nonRolling = (d&&(str==[d.getDate(),d.getMonth()+1,d.getFullYear()].join('/')));
  return (nonRolling) ? d : null;
}

[Edit2] If you want to match against zero-padded dates (e.g. "08/08/2013") then you could do something like this:

function parseDate(str) {
  function pad(x){return (((''+x).length==2) ? '' : '0') + x; }
  var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
    , d = (m) ? new Date(m[3], m[2]-1, m[1]) : null
    , matchesPadded = (d&&(str==[pad(d.getDate()),pad(d.getMonth()+1),d.getFullYear()].join('/')))
    , matchesNonPadded = (d&&(str==[d.getDate(),d.getMonth()+1,d.getFullYear()].join('/')));
  return (matchesPadded || matchesNonPadded) ? d : null;
}

However, it will still fail for inconsistently padded dates (e.g. "8/08/2013").

Solution 3:

Take a look from here https://www.regextester.com/?fam=114662

Use this following Regular Expression Details, This will support leap year also.

var reg = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(([1][26]|[2468][048]|[3579][26])00))))$/g;

Example