Regex para validar el formato de fecha dd / mm / aaaa

Necesito validar una cadena de fecha para el formato dd/mm/yyyy con una expresión regular.

Esta expresión regular valida dd/mm/yyyy , pero no las fechas no válidas como 31/02/4500 :

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

¿Qué es una expresión regular válida para validar el formato dd/mm/yyyy con soporte de año bisiesto?

La expresión regular que pegó no valida los años bisiestos correctamente, pero hay uno que lo hace en la misma publicación . Lo modifiqué para tomar dd/mm/yyyy , dd-mm-yyyy o dd.mm.yyyy

^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-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})$

Lo probé un poco en el enlace que Arun proporcionó en su respuesta y también aquí y parece funcionar.

He extendido la expresión regular dada por @Ofir Luzon para los formatos dd-mmm-YYYY, dd / mmm / YYYY, dd.mmm.YYYY según mi requisito. Cualquier otra persona con el mismo requisito puede referir esto

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

y probado para algunos casos de prueba aquí http://regexr.com/39tr1 .

Para una mejor comprensión de esta expresión regular refiérase a esta imagen: enter image description here

 dd/MM/yyyy: 

Verifica si año bisiesto. Los años desde 1900 hasta 9999 son válidos. Solo dd / 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)$) 

prueba esto.

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

puede probar la expresión regular en http://www.regular-expressions.info/javascriptexample.html fácilmente.

Para aquellos que miran esto y se confunden por completo, aquí hay un extracto de mi guión. Desafortunadamente, todo lo que hace es hacer coincidir los números válidos en una entrada de fecha y hora, y el 31 de febrero se marcará como válido, pero como muchos han dicho, la expresión regular realmente no es la mejor herramienta para realizar esta prueba.

Para hacer coincidir una fecha en el formato ‘aaaa-MM-dd hh: mm’ (O, de hecho, en el orden que desee)

 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", eg 2019-12-31 19:30'); return false; } 

La secuencia de comandos anterior comienza construyendo un objeto regex. A continuación, encuentra todas las entradas cuyos identificadores coinciden con un patrón determinado y luego recorre estos. No pruebo la primera entrada que encuentro ( if (e > 0) ).

Un poco de explicación:

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

^ significa el inicio del partido, mientras que $ significa el final del partido.

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

\d+ significa que coincide con una secuencia de enteros única o contigua, por lo que myhtml_element_with_id_56_datetime y myhtml_element_with_id_2_datetime coincidirán, pero myhtml_element_with_id_5a_datetime no lo hará

Aquí hay otra versión de regex que coincide con cualquiera de los siguientes formatos de fecha y permite omitir los ceros a la izquierda:

Regex: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$

Partidos:

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

Visualización de expresión regular

Demostración de Debuggex

Encontrado este reg ex aquí

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

Esto valida el formato mm/dd/yyyy y las fechas válidas correctamente (pero no m/d/yyyy ).

Algunas pruebas

Sospecho que lo siguiente es tan preciso como se puede esperar sin saber cuándo la configuración regional del usuario pasó del calendario juliano al gregoriano.

Acepta ‘-‘, ‘/’ o nada como separadores entre año, mes y día, sin importar el orden.

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

aaaaMMdd:

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

Aparte del orden, todos estos son precisos para el calendario juliano (año bisiesto cada cuatro años) hasta el 1700, cuando el calendario gregoriano se separa del juliano. Tiene dos problemas:

  1. Acepta el año 0000, que no existe en muchos estándares, pero no en todos. Tenga en cuenta que ISO 8601 acepta el año 0000 (equivalente a 1 BCE).
  2. No omite los 10-13 días que se perdieron cuando el Calendario Gregoriano comenzó a usarse. Esto varía según la localidad. Por ejemplo, la Iglesia Católica Romana saltó 10 días, del 5 de octubre al 14 de octubre de 1582, pero Grecia (la última en cambiar) se saltó del 16 al 28 de febrero de 1923, 13 días, teniendo en cuenta los años bisiestos de 1700, 1800 y 1900.

Esto se ha probado en comparación con la implementación del calendario de Java desde el año 0001 hasta el año 9999, siendo la única discrepancia los 10 días mencionados anteriormente en 1582.

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

validará cualquier fecha entre 1900-2099

La siguiente expresión es agradable y fácil de manipular:

 ((((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]))) 

Valida de acuerdo con el formato MM / dd / YYYY y permite el soporte de años bisiestos de 1960 a 2016. Si necesita extender el soporte del año bisiesto, solo necesita manipular esta parte de la expresión:

 (19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])) 

Espero que esto te haya ayudado mucho

Otra respuesta que valida el día (dd) dependiendo del mes (mm) y el año (aaaa) (es decir, también valida el 29 de febrero en años bisiestos) y permite años que varían de 0001 a 9999 (0000 en un año inválido según el gregoriano calendario)

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

Aquí escribí uno para dd/mm/yyyy donde el separador puede ser uno de -.,/ 0000-9999 range 0000-9999 .

Se trata de años bisiestos y está diseñado para sabores regex, que admiten lookaheads, grupos de captura y referencias. NO es válido para d/m/yyyy . Si es necesario, agregue más separadores a [-.,/]

 ^(?=\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}$ 

Prueba en regex101 ; como una cadena de 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}$" 

explicado:

 (?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 

Ver también SO FAQ de Regex ; Por favor, avíseme si falla.

Estoy trabajando con una API que solo acepta el formato MM / DD / YYYY. No pude encontrar ninguna otra publicación que haya sido tan exitosa como la respuesta de Ofir , así que la modifiqué y la vuelvo a publicar aquí para cualquiera que la necesite.

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

validará el formato MM/DD/YYYY con 1960 a 2028

si necesita ampliar el soporte del año bisiesto, agregue

 19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048]|3[26]|4[048]))) 

esto también es trabajo

 ^((((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 puede cambiar el formato mm-dd-yyyy de reemplazar [/] a [-] también puede consultar en línea http://regexr.com/

Para la fecha MM / DD / YYYY, puede usar

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

Verifica los días y polillas adecuados.

Recuerde que puede verificar su expresión regular en

regex101

que recomiendo 🙂

¡Que te diviertas!

 ^(((([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]))) 

esta expresión regular validará las fechas en formato:

12-30-2016 (mm-dd-aaaa) o 12-3-2016 (mm-d-aaaa) o 1-3-2016 (md-aaaa) o 1-30-2016 (m-dd-aaaa)