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 non valides comme 31/02/4500
:
^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$
Qu'est-ce qu'une expression régulière valide pour valider le format dd/mm/yyyy
avec la prise en charge des années bissextiles?
La regex que vous avez collée ne valide pas correctement les années bissextiles, mais il y en a une qui fait dans le même message . Je l'ai modifié pour prendre dd/mm/yyyy
, dd-mm-yyyy
ou 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 fourni par Arun dans sa réponse et aussi ici et cela semble fonctionner.
14 février 2019: j'ai supprimé une virgule contenue dans la regex qui autorisait des dates telles que 29-0,-11
J'ai prolongé la regex donnée par @Ofir Luzon pour les formats jj-mmm-AAAA, jj/mmm/AAAA, jj.mmm.AAAA selon mes besoins. Toute autre personne ayant les mêmes exigences peut en référer
^(?:(?: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 certains cas de test ici http://regexr.com/39tr1 .
Pour une meilleure compréhension de cette expression régulière, reportez-vous à cette image:
Remarquer:
Votre expression rationnelle ne fonctionne pas pendant des années "qui sont des multiples de 4 et 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, toutes les années au format\d00 sont classées dans la même classe d'années bissextiles, ce qui est incorrect. - MuchToLearn
Donc, cela ne fonctionne correctement que pour [1901 - 2099] (Whew) ????
jj/mm/aaaa:
Vérifie si année bissextile. Les années 1900 à 9999 sont valables. Seulement jj/mm/aaaa
(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)
essaye ça.
^(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 à l'adresse http://www.regular-expressions.info/javascriptexample.html facilement.
Je soupçonne que ce qui suit est aussi précis que possible sans savoir quand les paramètres régionaux de l'utilisateur sont passés du calendrier Julien aux calendriers grégorien.
Il accepte soit '-', '/' ou rien en tant que séparateur entre année, mois et jour, quel que soit l'ordre.
MMddyyyy:
^(((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))[-/]?[0-9]{4}|02[-/]?29[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
ddMMyyyy:
^(((0[1-9]|[12][0-9]|30)[-/]?(0[13-9]|1[012])|31[-/]?(0[13578]|1[02])|(0[1-9]|1[0-9]|2[0-8])[-/]?02)[-/]?[0-9]{4}|29[-/]?02[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
aaaaMMjj:
^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00)[-/]?02[-/]?29)$
Mis à part l'ordre, ceux-ci sont tous conformes au calendrier julien (année bissextile tous les quatre ans) jusqu'en 1700, lorsque le calendrier grégorien s'écarte de celui de Julien. Il a deux problèmes:
Cela a été testé avec l'implémentation du calendrier de Java de l'année 0001 à l'année 9999, la seule anomalie étant les 10 jours susmentionnés de 1582.
Pour ceux qui les regardent et sont complètement confus, voici un extrait de mon script. Malheureusement, tout ce qu'il fait est de faire correspondre les nombres valides dans une entrée de date et 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.
Faire correspondre une date au format 'aaaa-MM-jj hh: mm' (ou dans l'ordre de votre choix)
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 la construction d'un objet regex. Il trouve ensuite toutes les entrées dont l'identifiant correspond à un certain modèle, puis les parcourt en boucle. Je ne teste pas la première entrée trouvée (if (e > 0)
).
Un peu d'explication:
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
^
signifie début de match, alors que $
signifie fin de match.
return this.id.match(/myhtml_element_with_id_\d+_datetime/);
\d+
signifie correspondre à une séquence d'entiers ou à une séquence contiguë, donc myhtml_element_with_id_56_datetime
et myhtml_element_with_id_2_datetime
correspondent, mais myhtml_element_with_id_5a_datetime
ne le sera pas.
Voici une autre version de regex qui correspond à l’un des formats de date suivants et permet d’omettre les zéros de tête:
Regex: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$
Correspondances:
1/1/11 or 1.1.11 or 1-1-11 : true 01/01/11 or 01.01.11 or 01-01-11 : true 01/01/2011 or 01.01.2011 or 01-01-2011 : true 01/1/2011 or 01.1.2011 or 01-1-2011 : true 1/11/2011 or 1.11.2011 or 1-11-2011 : true 1/11/11 or 1.11.11 or 1-11-11 : true 11/1/11 or 11.1.11 or 11-1-11 : true
J'ai trouvé ce registre ex ici
^(((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])|((16|[2468][048]|[3579][26])00))))$
Ceci valide le format mm/dd/yyyy
et les dates valides correctement (mais pas m/d/yyyy
).
Ici, j’en ai écrit un pour dd/mm/yyyy
où le séparateur peut être l’un des -.,/
gamme d’années 0000-9999
.
Il traite avec années bissextiles et est conçu pour les goûts de regex, qui supporte lookaheads, capture de groupes et références arrière. NON valide pour tel que d/m/yyyy
. Si nécessaire, ajoutez des séparateurs supplémentaires à [-.,/]
^(?=\d{2}([-.,\/])\d{2}\1\d{4}$)(?:0[1-9]|1\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\d{4}$
Test à regex101 ; en tant que chaîne Java:
"^(?=\\d{2}([-.,\\/])\\d{2}\\1\\d{4}$)(?:0[1-9]|1\\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\\d{4}$"
a expliqué:
(?x) # modifier x: free spacing mode (for comments)
# verify date dd/mm/yyyy; possible separators: -.,/
# valid year range: 0000-9999
^ # start anchor
# precheck xx-xx-xxxx,... add new separators here
(?=\d{2}([-.,\/])\d{2}\1\d{4}$)
(?: # day-check: non caturing group
# days 01-28
0[1-9]|1\d|[2][0-8]|
# february 29d check for leap year: all 4y / 00 years: only each 400
# 0400,0800,1200,1600,2000,...
29
(?!.02. # not if feb: if not ...
(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
)
)|
# d30 negative lookahead: february cannot have 30 days
30(?!.02)|
# d31 positive lookahead: month up to 31 days
31(?=.(?:0[13578]|10|12))
) # eof day-check
# month 01-12
.(?:0[1-9]|1[012])
# year 0000-9999
.\d{4}
$ # end anchor
Voir aussi FAQ de SO Regex ; S'il vous plaît faites le moi savoir, si cela échoue.
"^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d)$"
validera toute date comprise entre 1900-2099
L'expression suivante est agréable et facile à manipuler:
((((0[13578]|1[02])(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)((\/|-|.)(0[1-9]|1[0-9]|2[0-8]))))(\/|-|.)(19([6-9][0-9])|20(0[0-9]|1[0-4])))|((02)(\/|-|.)(29)(\/|-|.)(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])))
Il valide selon le format MM/jj/AAAA et permet une prise en charge d'une année bissextile de 1960 à 2016. Si vous avez besoin d'une prise en charge d'une année bissextile étendue, il vous suffit de manipuler cette partie de l'expression:
(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]))
J'espère que cela vous a beaucoup aidé
Une autre réponse qui valide le jour (jj) en fonction du mois (mm) et de l’année (aaaa) (c’est-à-dire valide également le 29 février dans les années bissextiles) et permet des années comprises entre 0001 et 9999 (0000 dans une année non valide selon le Grégorien). calendrier)
^(?:(?:(?:0[1-9]|[12]\d|3[01])/(?:0[13578]|1[02])|(?:0[1-9]|[12]\d|30)/(?:0[469]|11)|(?:0[1-9]|1\d|2[0-8])/02)/(?!0000)\d{4}|(?:(?:0[1-9]|[12]\d)/02/(?:(?!0000)(?:[02468][048]|[13579][26])00|(?!..00)\d{2}(?:[02468][048]|[13579][26]))))$
Je travaille avec une API qui uniquement accepte le format MM/JJ/AAAA. Je ne pouvais trouver aucune autre publication faisant des années bissextiles aussi bien que réponse d'Ofir , alors je l'ai modifiée et je la rediffuse ici pour tous ceux qui pourraient en avoir besoin.
/^(?:(?:(?:0[13578]|1[02])(\/)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
Je sais que c'est une réponse tangentielle à la question, mais si l'intention de la question est 'Comment valider une date?', Alors pourquoi ne pas laisser le langage de programmation faire le travail difficile ( si vous utilisez une langue qui peut)?
par exemple. en php
$this_date_object = date_create($this_date);
if ($this_date_object == false )
{
// process the error
}
((((0[13578]|1[02])\/(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)\/(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)(\/(0[1-9]|1[0-9]|2[0-8]))))\/(19([6-9][0-9])|20([0-9][0-9])))|((02)\/(29)\/(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
validera le format MM/DD/YYYY
avec 1960
à 2028
si vous devez prolonger l’année bissextile, ajoutez
19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048]|3[26]|4[048])))
c'est aussi du travail
^((((0[13578]|1[02])[/](0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)[/](0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)([/](0[1-9]|1[0-9]|2[0-8]))))[/](19([6-9][0-9])|20([0-9][0-9])))|((02)[/](29)[/](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
si vous pouvez changer le format mm-dd-yyyy
puis remplacer [/]
par [-]
, vérifiez également en ligne http://regexr.com/
Pour la date MM/JJ/AAAA, vous pouvez utiliser
^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$
Il vérifie les jours et les mites appropriés.
Rappelez-vous que vous pouvez vérifier votre expression régulière à
que je recommande :)
S'amuser!
^(((([13578]|0[13578]|1[02])[-](0[1-9]|[1-9]|1[0-9]|2[0-9]|3[01]))|(([469]|0[469]|11)[-]([1-9]|1[0-9]|2[0-9]|3[0]))|((2|02)([-](0[1-9]|1[0-9]|2[0-8]))))[-](19([6-9][0-9])|20([0-9][0-9])))|((02)[-](29)[-](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
cette expression régulière validera les dates au format:
12-30-2016 (mm-jj-aaaa) ou 12-3-2016 (mm-j-aaaa) ou 1-3-2016 (m-j-aaaa) ou 1-30-2016 (m-jj-aaaa)