238 votes

Regex pour valider les formats de date dd/mm/YYYY, dd-mm-YYYY, dd.mm.YYY, dd mmm YYYY, dd-mmm-YYY, dd/mmm/YYYY, dd.mmm.YYY avec support des années bissextiles

J'ai besoin de valider une chaîne de date pour le format dd/mm/yyyy avec une expression régulière.

Cette regex valide dd/mm/yyyy mais pas les dates invalides comme 31/02/4500 :

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

Quelle est une regex valide pour valider dd/mm/yyyy avec prise en charge des années bissextiles ?

415voto

Ofir Luzon Points 1289

L'expression que vous avez collée ne valide pas correctement les années bissextiles, mais il en existe une qui le fait. dans le même message . Je l'ai modifié pour prendre dd/mm/yyyy , dd-mm-yyyy o dd.mm.yyyy .

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

Je l'ai testé un peu dans le lien qu'Arun a fourni dans sa réponse et également ici et cela semble fonctionner.

Editer le 14 février 2019 : j'ai supprimé une virgule qui se trouvait dans le regex qui permettait des dates comme . 29-0,-11

289voto

Alok Chaudhary Points 3171

J'ai étendu la regex donnée par @Ofir Luzon pour les formats dd-mmm-YYYY, dd/mmm/YYYY, dd.mmm.YYYY selon mes besoins. Toute autre personne ayant les mêmes besoins peut se référer à ceci

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

et testé pour quelques cas de test ici https://regexr.com/39tr1 .

Pour une meilleure compréhension de cette expression régulière, référez-vous à cette image :

enter image description here

Modifier

Extension pour yyyy/mm/dd, yyyy-mm-dd ou yyyy.mm.dd quelques cas de test https://regex101.com/r/3TZfyU/1

^(?:(?:1[6-9]|[2-9]\d)?\d{2})(?:(?:(\/|-|\.)(?:0?[13578]|1[02])\1(?:31))|(?:(\/|-|\.)(?:0?[13-9]|1[0-2])\2(?:29|30)))$|
^(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)0?2\3(?:29)$|
^(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:0?[1-9]|1\d|2[0-8])$

82voto

gdZeus Points 71

Avis :

Votre regexp ne fonctionne pas pour les années qui "sont des multiples de 4 et de 100, mais pas de 400". Les années qui passent ce test ne sont pas des années bissextiles. Par exemple : 1900, 2100, 2200, 2300, 2500, etc. En d'autres termes, il met toutes les années avec le format \d\d00 dans la même classe d'années bissextiles, ce qui est incorrect. - MuchToLearn

S

33voto

Aaron Points 1857

Essayez ceci.

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

vous pouvez tester l'expression régulière à http://www.regular-expressions.info/javascriptexample.html facilement.

14voto

Luke Madhanga Points 353

Pour ceux qui les regardent et sont complètement perdus, voici un extrait de mon script. Malheureusement, tout ce qu'il fait est de faire correspondre des chiffres valides dans une entrée de date et d'heure, et le 31 février sera marqué comme valide, mais comme beaucoup l'ont dit, regex n'est vraiment pas le meilleur outil pour faire ce test.

Pour faire correspondre une date au format 'yyyy-MM-dd hh:mm' (ou dans l'ordre que vous voulez)

var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])';            ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])';               ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])';   ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])';            ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])';                    ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
    if (e > 0) {
        // Don't test the first input. This will use the default
        var val = $(this).val();
        if (val && !val.trim().match(reg)) {
            dateerrors = true;
            return false;
        }
    }
});
if (dateerrors) {
    alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
    return false;
}

Le script ci-dessus commence par construire un objet regex. Il trouve ensuite toutes les entrées dont les identifiants correspondent à un certain motif, puis les parcourt en boucle. Je ne teste pas la première entrée que je trouve ( if (e > 0) ).

Un peu d'explication :

var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');

^ signifie le début du match, tandis que $ signifie la fin du match.

return this.id.match(/myhtml_element_with_id_\d+_datetime/);

\d+ signifie faire correspondre un seul ou une séquence contiguë d'entiers, donc myhtml_element_with_id_56_datetime y myhtml_element_with_id_2_datetime correspondra, mais myhtml_element_with_id_5a_datetime ne sera pas

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X