Come scrivere regex per convalidare le date?

Sto lavorando in JavaScript e ho bisogno di capire come determinare una data valida usando le espressioni regolari.

Le partite saranno:

dd-mm-yyyy dd-mm-yy 

Inoltre, nessun zero iniziale dovrebbe essere accettato come:

 9-8-2010 10-6-99 

Come posso scrivere un’espressione regolare per farlo?

Mi sono inventato questo:

 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; } 

Funziona per dd-mm-yyyy , dd-mm-yy , dm-yyyy e dm-yy , usando - o / come separatori

Basato su questo script

Faresti meglio a dividere e testare tutti gli elementi. Ma se vuoi davvero usare una regex puoi provare questo:

 /^(?:(?: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))$/ 

Spiegazione:

 ^ # 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) ) $ 

Ho spiegato la prima parte, lasciando il resto come esercizio.

Questo match una data non valida: 29-02-1900 ma è corretta per qualsiasi data tra 01-01-1900 e 31-12-2099

Soluzione passo-passo:

 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; } 

Ho ottenuto alcuni risultati per convalidare il formato mm / gg / aaaa

 ^(((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))$ 

Questa variazione convalida “ddmmyy” senza delimitatori.

 ^(?:(?:(?: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))$ 

(è stato testato su debuggex). … e convalida comunque gli anni bisestili di due cifre in questo secolo.

Per validare yyyy-mm-gg hh: MM in modo semplicistico (24 ore ora):

 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'); }; 

La modifica del primo termine (da 20 \ d {2}) a \ d {4} consentirà qualsiasi anno a 4 cifre, inclusi 0000 e 9999. Inoltre, questa regex impone gli zeri iniziali per mese, giorno, ore e minuti.

Questa espressione regolare verifica:

  • l’anno per essere 20xx; cambia alle tue preferenze.
  • zeri iniziali per mese, giorno, ore e minuti

Questa espressione regolare non verifica:

  • Precisione mese / giorno (consentirà ad esempio il 30 febbraio e il 31 giugno)
  • Anni bisestili
  • AM o PM (è per 24 ore)

Cosa ne pensi di questo?

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

Non ho provato questo. E questo non convalida gli anni bisestili