Validate a date dd / mm / yyyy with regular expressions

9

The file% co_of% validation date JS fails if you put as days 10 and 20.
The code is this:

function validaEdat(){
    vesSumant();
    vfalladata = false;

    //Comprovació de la data de naixement i el correu electrònic
    var vregexNaix = /^([012][1-9]|3[01])(\/)(0[1-9]|1[012])(\d{4})$/;


    vdataNaix = document.formu.dataNaix.value;
    vanyData = vdataNaix.substring(vdataNaix.length-4, 4);

    if((!vregexNaix.test(vdataNaix)) || (/^(\d{4})$/.test(vanyData))){
        alert("Bonvolu skribi naskighdato per tt/mm/jjjj. \n--------------------------------------\n Per favor, empleneu la data com dd/mm/aaaa.");
        document.formu.dataNaix.value = "";
        document.formu.dataNaix.focus();
        return false;
    }

    controlaCaselles();
    return true;
}
    
asked by Joan Inglada Roig 31.03.2017 в 16:40
source

5 answers

18

Validate a date

Validate a date with a regular expression, although it is possible, it is impractical and there are very few cases in which I would recommend it. For me, the limitation is: Do you understand every part of the regex? Are you going to understand it easily in a few years? If another developer would have to edit your code, could you easily understand it?

There are many, simpler alternatives to validate dates:

  • HTML5 incorporated a new type of <input> , Input Type Date (see compatibility !).

    document.getElementById("input-fecha")
      .addEventListener("input", function(evt) {
        let fechaIngresada = evt.target.value;
        //Fecha válida?
        if (fechaIngresada) {
            document.getElementById("salida")
              .innerText = fechaIngresada;
        } else {
            document.getElementById("salida")
              .innerText = "Fecha Inválida";
        }
      });
    <input id="input-fecha" type="date" required="required" min="1920-01-01" max="2999-12-31">
    <pre id="salida"></pre>
  • Use Moment.js , which generates a wrapper for Date (or can even be carried to Date).

    let formatos = ['D/M/YYYY', 'D-M-YYYY'],
        a,b,c,
        fecha;
    
    //validar
    a = moment('29/2/2016',  formatos, true).isValid();  // true
    b = moment('29/02/2017', formatos, true).isValid();  // false
    c = moment('1-1-1900',   formatos, true).isValid();  // true
    console.log(a,b,c);
    
    //convertir en Date
    fecha = moment('29/02/2016', formatos, true).toDate();
    console.log('Fecha: ' + fecha);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
  • Convert to Date and see if it keeps the same value.

    function convertirFecha(texto) {
        let partes = (texto || '').split('/'),
            fechaGenerada = new Date(partes[2], --partes[1], partes[0]);
        
        if (partes.length == 3 && fechaGenerada
         && partes[0] == fechaGenerada.getDate()
         && partes[1] == fechaGenerada.getMonth()
         && partes[2] == fechaGenerada.getFullYear()) {
            return fechaGenerada;
        }
        return false; //Inválida
    }
    
    console.log(convertirFecha('29/2/2016')); //fecha (evalúa true)
    console.log(convertirFecha('29/2/2017')); //false
    
       
  • Use a regex to validate that they are digits, and then manually validate each value.

    function fechaValida(texto) {
        let partes = /^(\d{1,2})[/](\d{1,2})[/](\d{3,4})$/.exec(texto);
        
        if (!partes) return false; //no coincide el regex
    
        //Obtener las partes
        let d = parseInt(partes[1], 10),
            m = parseInt(partes[2], 10),
            a = parseInt(partes[3], 10);
    
        //Validar manualmente
        if (!a || !m || m > 12 || !d) return false;
    
        let diasPorMes = [31,28,31,30,31,30,31,31,30,31,30,31 ];
    
        //Si es bisiesto, febrero tiene 29
        if (m == 2 && (a % 4 == 0 && a % 100 != 0) || a % 400 == 0)
            diasPorMes[1] = 29;
    
        //Que no tenga más días de los permitidos en el mes
        if (d > diasPorMes[m - 1]) return false;
        
        //Fecha válida
        return new Date(a,m,d);
    }
    
    console.log(fechaValida('29/2/2016')); //fecha (evalúa true)
    console.log(fechaValida('29/2/2017')); //false
  • With jQuery and jQuery UI , using the wiget Datepicker . You can show the widget, or not. You only need to call the method $.datepicker.parseDate() . In the example, you can enter the date in the input or in the datepicker. However, the input could be disabled so that it is not entered manually. But, another alternative is not to use an input, and to show the datepicker constantly in a div.

    $(function() { // Gestor para $(document).ready()
    
      // jQuery UI Datepicker
      //  - http://api.jqueryui.com/datepicker/
      $.datepicker.setDefaults(
        $.datepicker.regional["es"]
      );
    
      let opciones = {
        dateFormat: "dd/mm/yy",
        yearRange: "1500:",
        maxDate: "2w",
        defaultDate: 0,
        constrainInput: true,
        autoSize: true,
        appendText: "(d/m/aaaa)",
        showAnim: "slideDown",
        numberOfMonths: 1,
        showButtonPanel: true,
        changeMonth: true,
        changeYear: true,
        showMonthAfterYear: false,
        firstDay: 0,
        showWeek: false,
        /*
        prevText: "≪ Ant",
        nextText: "Sig ≫",
        closeText: "Cerrar",
        currentText: "Hoy",
        weekHeader: "N°",
        dayNames: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
        dayNamesShort: ["Dom", "Lun", "Mar", "Mié", "Juv", "Vie", "Sáb"],
        dayNamesMin: ["D", "L", "M", "Mi", "J", "V", "S"],
        monthNames: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
        monthNamesShort: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
        */
    
        //Evento cuando se selecciona una fecha
        onSelect: validarFecha
      };
    
      //Inicializar el Datepicker
      let datepicker = $('#fecha').datepicker(opciones);
    
      //Evento cuando se cambia
      $("#fecha").on("input", validarFecha);
    });
    
    
    //Validar la fecha cuando cambia el valor de la fecha
    //Disparado input.on("input") y datepicker.onSelect
    function validarFecha() {
      try {
        //Si es inválida dispara el error
        let fecha = $.datepicker.parseDate("dd/mm/yy", $("#fecha").val());
        // mostrar la fecha válida
        $("#salida").text(
          "Fecha válida:\n" + fecha
        );
      } catch (err) {
        // mostrar error
        $("#salida").text("Fecha INVÁLIDA");
      }
    }
    <!-- Referencias al DatePicker -->
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/i18n/jquery-ui-i18n.min.js"></script>
    
    <!-- HTML -->
    <pre id="salida" style="height: 3em"></pre>
    <input type="text" id="fecha" name="fecha" placeholder="Ingrese la fecha">
  • Use bootstrap-datepicker (similar to the previous one).

    $(function() {
      //Inicializar el datepicker
      // - Sandbox: https://uxsolutions.github.io/bootstrap-datepicker/
      $('#fecha').datepicker({
        format: "dd/mm/yyyy",
        weekStart: 0,
        todayBtn: true,
        language: "es",
        daysOfWeekHighlighted: "0,6",
        todayHighlight: true
      }).on("changeDate", function(e) {
        //e.date también tiene la fecha
        $("#salida").text(
          "Fecha:\n" +
          $('#fecha').datepicker("getDate")
        );
      });
    });
    <!-- Referencias a bootstrap-datepicker -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/locales/bootstrap-datepicker.es.min.js"></script>
    <link id="bs-css" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
    <link id="bsdp-css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker3.min.css" rel="stylesheet">
    
    
    <!-- HTML -->
    <div id="fecha"></div>
    <pre id="salida"></pre>
  • RegEx to validate any date d / m / yyyy regex101.com

    Validate any date, including the days of February in leap years.

    /^(?:(?:(?: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]))[/](?:0{2,3}[1-9]|0{1,2}[1-9]\d|0?[1-9]\d{2}|[1-9]\d{3})|29[/]0?2[/](?:\d{1,2}(?:0[48]|[2468][048]|[13579][26])|(?:0?[48]|[13579][26]|[2468][048])00))$/
    


    Code to validate and extract day, month and year (detailed with variables)

    On the previous expression, we use parentheses (groups) to obtain each of the parts:

     /^(?:(?:(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]))[/](0{2,3}[1-9]|0{1,2}[1-9]\d|0?[1-9]\d{2}|[1-9]\d{3})|(29)[/](0?2)[/](\d{1,2}(?:0[48]|[2468][048]|[13579][26])|(?:0?[48]|[13579][26]|[2468][048])00))$/
    

    //Devuelve el regex para validar una fecha.
    // - dividido en variables para que se entienda y se pueda mantener/editar.
    //
    function regexValidarFecha() {
        let sep              = "[/]",
        
            dia1a28          = "(0?[1-9]|1\d|2[0-8])",
            dia29            = "(29)",
            dia29o30         = "(29|30)",
            dia31            = "(31)",
            
            mes1a12          = "(0?[1-9]|1[0-2])",
            mes2             = "(0?2)",
            mesNoFeb         = "(0?[13-9]|1[0-2])",
            mes31dias        = "(0?[13578]|1[02])",
            
            diames29Feb      = dia29+sep+mes2,
            diames1a28       = dia1a28+sep+mes1a12,
            diames29o30noFeb = dia29o30+sep+mesNoFeb,
            diames31         = dia31+sep+mes31dias,
            diamesNo29Feb    = "(?:"+diames1a28+"|"+diames29o30noFeb+"|"+diames31+")",
            
            anno1a9999     = "(0{2,3}[1-9]|0{1,2}[1-9]\d|0?[1-9]\d{2}|[1-9]\d{3})",
            annoMult4no100   = "\d{1,2}(?:0[48]|[2468][048]|[13579][26])",
            annoMult400      = "(?:0?[48]|[13579][26]|[2468][048])00",
            annoBisiesto     = "("+annoMult4no100+"|"+annoMult400+")",
            
            fechaNo29Feb     = diamesNo29Feb+sep+anno1a9999,
            fecha29Feb       = diames29Feb+sep+annoBisiesto,
            
            fechaFinal       = "^(?:"+fechaNo29Feb+"|"+fecha29Feb+")$";
        
        return new RegExp(fechaFinal);
    }
    
    //Valida una fecha ingresada como "m/d/aaaa"
    // - Si no es válida, devuelve false
    // - Si es válida, devuelve un objeto {d:"día",m:"mes",a:"año",date:date}
    // - Parámetro: UTC (opcional) si se debe devolver {date:(date)} en UTC
    //
    function validarFecha(texto, UTC = false) {
        let fechaValida = regexValidarFecha(),
            // fechaValida = /^(?:(?:(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]))[/](0{2,3}[1-9]|0{1,2}[1-9]\d|0?[1-9]\d{2}|[1-9]\d{3})|(29)[/](0?2)[/](\d{1,2}(?:0[48]|[2468][048]|[13579][26])|(?:0?[48]|[13579][26]|[2468][048])00))$/,
            grupos;
            
        if (grupos = fechaValida.exec(texto)) {
            //Unir día mes y año desde los grupos que pueden haber coincidido
            let d = [grupos[1],grupos[3],grupos[5],grupos[8]].join(''),
                m = [grupos[2],grupos[4],grupos[6],grupos[9]].join(''),
                a = [grupos[7],grupos[10]].join(''),
                date = new Date(0);
    
            //Obtener la fecha en formato local o UTC
            if (UTC) {
                date.setUTCHours(0);
                date.setUTCFullYear(a,parseInt(m,10) - 1,d);
            } else {
                date.setHours(0);
                date.setFullYear(a,parseInt(m,10) - 1,d);
            }
            
            //Devolver como objeto con cada número por separado
            return {
                d: d,
                m: m,
                a: a,
                date: date
            };
        }
        return false; //No es fecha válida
    }
    
    
    // -----------
    //   PRUEBA
    // -----------
    let inputFecha = document.getElementById("input-fecha");
    
    //asociar evento cuando se modifique el input
    inputFecha.addEventListener("input",function(evt){
        let texto = evt.target.value,
            salida = document.getElementById("salida"),
            resultado;
        
        //VALIDAR    
        resultado = validarFecha(texto);
    
        if (resultado) {
            salida.innerText =
                "Día: "     + resultado.d +
                "\nMes: "   + resultado.m +
                "\nAño: "   + resultado.a +
                "\nFecha:\n"+ resultado.date;
        } else {
            salida.innerText = "Fecha incorrecta";
        }
    });
    inputFecha.dispatchEvent(new Event('input')); //validar al iniciar
    <input id="input-fecha" type="text"
           placeholder="Ingrese una fecha (d/m/aaa)"
           value="29/02/2016"
           style="width: 100%">
    <pre   id="salida"></pre>
        
    answered by 02.04.2017 / 13:30
    source
    4

    The problem is in the RegExp vregexNaix , which does not accept either the 10 or the 20

    One solution would be to modify this RegExp , for example like this:

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

    Demo:

    var vregexNaix = /^(0[1-9]|[1-2]\d|3[01])(\/)(0[1-9]|1[012])(\d{4})$/;
    console.log(vregexNaix.test('10/12/1992'));
    console.log(vregexNaix.test('20/10/2082'));
        
    answered by 31.03.2017 в 16:55
    2

    I think the easiest way to validate a date without so much code would be:

    <html>
        <head><title>Validar una fecha dd/mm/aaaa con JavaScript</title></head>
       <body>
    
    <script type="text/javascript"><!--
       function esfechavalida() {
          var fecha = document.forma.fecha.value;
    
          // La longitud de la fecha debe tener exactamente 10 caracteres
          if ( fecha.length !== 10 )
             error = true;
    
          // Primero verifica el patron
          if ( !/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(fecha) )
             error = true;
    
          // Mediante el delimitador "/" separa dia, mes y año
          var fecha = fecha.split("/");
          var day = parseInt(fecha[0]);
          var month = parseInt(fecha[1]);
          var year = parseInt(fecha[2]);
    
          // Verifica que dia, mes, año, solo sean numeros
          error = ( isNaN(day) || isNaN(month) || isNaN(year) );
    
          // Lista de dias en los meses, por defecto no es año bisiesto
          var ListofDays = [31,28,31,30,31,30,31,31,30,31,30,31];
          if ( month === 1 || month > 2 )
             if ( day > ListofDays[month-1] || day < 0 || ListofDays[month-1] === undefined )
                error = true;
    
          // Detecta si es año bisiesto y asigna a febrero 29 dias
          if ( month === 2 ) {
             var lyear = ( (!(year % 4) && year % 100) || !(year % 400) );
             if ( lyear === false && day >= 29 )
                error = true;
             if ( lyear === true && day > 29 )
                error = true;
          }
    
          if ( error === true ) {
             alert("Fecha Inválida: * La Fecha debe tener el formato: dd/mm/aaaa (dia/mes/año).\n");
             return false;
          }
          else
             alert("Fecha Válida\n");
    
          return true;
       }
    //--></script>
    
          <form name="forma" action="http://localhost:8888/esfecha.html" method="post">
             <table>
                <tr>
                   <td>
                      Fecha:
                      <input type="text" name="fecha" maxlength="10" id="fecha" onchange="return esfechavalida();" />
                   </td>
                   <td>
                       <input type="submit" value="Submit">
                   </td>
                </tr>
             </table>
          </form>
       </body>
    </html>
    
        
    answered by 21.04.2018 в 22:50
    -3
    <script>
    
        var disabledDays = ["31-12-2019","1-1-2020","1-1-2018","12-2-2018","13-2-2018","29-3-2018","30-3-2018","9-4-2018","1-5-2018","5-7-2018","24-7-2018","12-10-2018","24-12-2018","25-12-2018","31-12-2018","1-1-2019","4-3-2019","5-3-2019","18-4-2019","19-4-2019","1-5-2019","24-6-2019","5-7-2019","24-7-2019","12-10-2019","24-12-2019","24-2-2020","25-2-2020","9-4-2020","10-4-2020","19-4-2020","1-5-2018","24-6-2020","5-7-2020","24-7-2020","12-10-2020","24-12-2020","25-12-2020","31-12-2020","25-12-2019","31-12-2021","6-5-2018","24-6-2018","11-9-2018","18-9-2018","20-9-2018","21-9-2018","28-9-2018","4-9-2018","5-9-2018","6-9-2018","13-9-2018","12-9-2018","14-9-2018","27-9-2018","19-9-2018","26-9-2018","25-9-2018","3-10-2018","9-10-2018","10-10-2018","11-10-2018","2-10-2018","5-10-2018","4-10-2018"];
    
        jQuery(document).ready(function() {
            jQuery('#fecha_cita').datepicker({
                dateFormat: 'dd-mm-yy',
                constrainInput: true,
                minDate: 'today',
                maxDate: '+1m',
                beforeShowDay: noWeekendsOrHolidays
            });
        });
    
    
        function nationalDays(date) {
            var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
            for (i = 0; i < disabledDays.length; i++) {
                if ($.inArray(d + '-' + (m + 1) + '-' + y, disabledDays) != -1 || "" > date) {
                    return [false];
                }
            }
            return [true];
        }
    
        function noWeekendsOrHolidays(date) {
            var noWeekend = $.datepicker.noWeekends(date);
            if (noWeekend[0]) {
                var isNotFriday = noFridays(date);
                if (isNotFriday[0]) {
                    return nationalDays(date);
                }
                else {
                    return isNotFriday;
                }
            }
            else {
                return noWeekend;
            }
        }
    
        function noFridays(date) {
            var day = date.getDay();
            return [(day != 0 && day != 6 && day != 1), ""];
        }
    </script>
    

    as valid the date 10-16-2018 please

        
    answered by 21.09.2018 в 05:40
    -4

    Add ( - ) to validate "01-03-1993" .

    /^(?:(?:(?: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]))[/-](?:0{2,3}[1-9]|0{1,2}[1-9]\d|0?[1-9]\d{2}|[1-9]\d{3})|29[/-]0?2[/-](?:\d{1,2}(?:0[48]|[2468][048]|[13579][26])|(?:0?[48]|[13579][26]|[2468][048])00))$/
    
        
    answered by 18.01.2018 в 19:30