How to validate date with AngularJS or jQuery?

6

I have a simple input that gets a date, how do I validate that date if it's true?

For example:

  

31/02/2006 this does not exist
  20/20/9999 this does not exist

<input name="data" 
 ui-mask="99/99/9999"
 kendo-date-picker name="t"
 ng-model="model.data"
 k-format="'dd/MM/yyyy'">

That is to validate days, months and years.

Is there anything in Angular ready for this? Or if Javascript is better, show me the simplest way.

    
asked by anonymous 08.10.2015 / 16:16

6 answers

3

I'll give you a code that I use here in pure javascript, this monster validates everything will solve your problem:

        function validateDate(id) {
      var RegExPattern = /^((((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])      [\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/;

     if (!((id.value.match(RegExPattern)) && (id.value!=''))) {
          alert('Data inválida.');
   id.focus();
        }
       else
        alert('Data válidaa.');
    }
    
13.10.2015 / 02:03
6

Simple way, using pure javascript:

Try to do a parse dynamic via Date() constructor. If it works, the date is valid. Example for dates in imperial format:

var isValidDate = function(str) {
    return !!new Date(str).getTime();
}

Or the Brazilian version:

var isValidDate = function(str) {
    return str == 'dd/mm/yyyy' || 
           ( /^\d{2}\/\d{2}\/\d{4}$/.test(str) && new Date(str).getTime() );
}

For your examples,

isValidDate('31/02/2006'); // false
isValidDate('20/20/9999'); // false

However,

isValidDate('01/31/2006'); //true
isValidDate('01/20/9999'); //true

Executable version below (in Chrome, press F12 before clicking Run code snippet so you can see the console log):

var isValidDate = function(str) {
    return !!new Date(str).getTime();
}

console.log(isValidDate('31/02/2006'));
console.log(isValidDate('20/20/9999'));

console.log(isValidDate('01/31/2006'));
console.log(isValidDate('01/20/9999'));
    
08.10.2015 / 17:25
5

Follows:

Regular expression:

function isValidDate(date)
{
    var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
    if (matches == null) return false;
    var d = matches[2];
    var m = matches[1] - 1;
    var y = matches[3];
    var composedDate = new Date(y, m, d);
    return composedDate.getDate() == d &&
            composedDate.getMonth() == m &&
            composedDate.getFullYear() == y;
}

Policy (Angular)

var app = angular.module("myApp",[]);

function Fiddle($scope){}

app.directive('input-data', function() {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function(scope, elm, attr, ctrl) {
            if (!ctrl) {
                return;
            }

            elm.bind('keyup', function () {

                var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(this.value);
                if(matches){
                var d = matches[1];
                var m = matches[2] - 1;
                var y = matches[3];

                var composedDate = new Date(y, m, d); 
                var valid = composedDate.getDate() == d &&
                    composedDate.getMonth() == m &&
                    composedDate.getFullYear() == y;
                }

                if(!matches || !valid)
                    elm.attr('style', 'border:solid 3px #FE2E2E');
                else
                    elm.removeAttr('style');
            });
        }
    };
});

var app = angular.module("myApp", []);

function Fiddle($scope) {}

app.directive('input', function() {
  return {
    restrict: 'E',
    require: '?ngModel',
    link: function(scope, elm, attr, ctrl) {
      if (!ctrl) {
        return;
      }


      elm.bind('keyup', function() {

        var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(this.value);
        if (matches) {
          var d = matches[1];
          var m = matches[2] - 1;
          var y = matches[3];


          var composedDate = new Date(y, m, d);
          var valid = composedDate.getDate() == d &&
            composedDate.getMonth() == m &&
            composedDate.getFullYear() == y;
        }

        if (!matches || !valid)
          elm.attr('style', 'border:solid 3px #FE2E2E');
        else
          elm.removeAttr('style');
      });
    }
  };
});



function validarData() {
  var valid = isValidDate(document.getElementById("ipData").value);
  document.getElementById("ipData").style.border = (!valid ? 'solid 3px #FE2E2E' : '');
};


function isValidDate(date) {
  var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
  if (matches == null) return false;
  var d = matches[2];
  var m = matches[1] - 1;
  var y = matches[3];
  var composedDate = new Date(y, m, d);
  return composedDate.getDate() == d &&
    composedDate.getMonth() == m &&
    composedDate.getFullYear() == y;
}
html,
body {
  height: 100%;
}
body,
form {
  padding: 1em;
}
input,
input.ng-invalid.has-visited.has-focus,
form {
  border: 1px solid #8d8d8d;
}
input,
button {
  border-radius: 3px;
  padding: .25em;
}
body {
  background: #528cc2;
  /* Old browsers */
  background: -moz-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6dbbff), color-stop(100%, #528cc2));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #6dbbff 0%, #528cc2 100%);
  /* IE10+ */
  background: linear-gradient(to bottom, #6dbbff 0%, #528cc2 100%);
  /* W3C */
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#6dbbff', endColorstr='#528cc2', GradientType=0);
  /* IE6-9 */
  font-family: sans-serif;
}
ul,
li {
  list-style: none;
}
form {
  background: #f7f7f7;
  /* Old browsers */
  background: -moz-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f7f7f7), color-stop(100%, #e5e5e5));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #f7f7f7 0%, #e5e5e5 100%);
  /* IE10+ */
  background: linear-gradient(to bottom, #f7f7f7 0%, #e5e5e5 100%);
  /* W3C */
  filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7', endColorstr='#e5e5e5', GradientType=0);
  /* IE6-9 */
  border: 1px solid #8d8d8d;
  border-radius: 6px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, .3);
  min-width: 400px;
  margin: auto;
  width: 50%;
}
form li {
  margin-bottom: .5em;
}
label {
  color: #8d8d8d;
  display: block;
  line-height: 1.5;
}
:focus {
  outline: 0;
}
input {
  background: rgba(255, 255, 255, .5);
}
input:focus {
  background: #FFF;
}
input.ng-invalid.has-visited {
  border: 1px solid #E44848;
}
input.ng-valid.has-visited {
  border: 1px solid #a3bf57;
}
.error-message {
  color: #E44848;
}
button {
  background: #528CC2;
  color: white;
  cursor: pointer;
  border: 0;
}
button:disabled {
  background: rgba(82, 140, 194, 0.5);
  color: rgba(255, 255, 255, .5);
  font-weight: 400;
}
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><formname="myForm" novalidate ng-app="myApp">
  <ul ng-controller="Fiddle">
    <li>
      <label for="barthirty">Diretiva Angular</label>
      <input input-data type="datetime" ng-model="barthirty" required />

    </li>
  </ul>
  <ul>
    <li>
      <label for="barthirty">Expressao regular</label>
      <input type="datetime" id="ipData" required onkeyup="validarData()"/>
    </li>
  </ul>
  <button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
    
08.10.2015 / 16:40
5

You can use jQuery Validation to validate your fields. It is only in English, but has some libraries for translation. An alternative is to use these extensions.

Where you add validation to your form, like this:

$( "#myform" ).validate({
  rules: {
    data: {
      required: true,
      dateBR: true
    }
  }
});

And to translate the validations, you add this method:

jQuery.validator.addMethod("dateBR", function (value, element) {
    //contando chars    
    if (value.length != 10) return (this.optional(element) || false);
    // verificando data
    var data = value;
    var dia = data.substr(0, 2);
    var barra1 = data.substr(2, 1);
    var mes = data.substr(3, 2);
    var barra2 = data.substr(5, 1);
    var ano = data.substr(6, 4);
    if (data.length != 10 || barra1 != "/" || barra2 != "/" || isNaN(dia) || isNaN(mes) || isNaN(ano) || dia > 31 || mes > 12) return (this.optional(element) || false);
    if ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia == 31) return (this.optional(element) || false);
    if (mes == 2 && (dia > 29 || (dia == 29 && ano % 4 != 0))) return (this.optional(element) || false);
    if (ano < 1900) return (this.optional(element) || false);
    return (this.optional(element) || true);
}, "Informe uma data válida"); 

In this way you will be validating dates larger than 1900. Remember that it is necessary to separate by / . But the mask I believe you are already doing.

For your example, it would look like this:

<html><head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title> - Validade Example</title>
  <script type="text/javascript" src="//code.jquery.com/jquery-2.1.0.js"></script>
  <script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
  <link rel="stylesheet" type="text/css" href="/css/result-light.css">
      <script type="text/javascript" src="http://jqueryvalidation.org/files/dist/jquery.validate.min.js"></script><styletype="text/css"></style>
    
<body>
  <form id="myform" novalidate="novalidate">
<label for="data">Data: </label>
<input class="left" id="data" name="data">
<br>
<input type="submit" value="Validate!">
</form>
    
    <script>
// just for the demos, avoids form submit
jQuery.validator.setDefaults({
  debug: true,
  success: "valid"
});
      jQuery.validator.addMethod("dateBR", function (value, element) {
    //contando chars    
    if (value.length != 10) return (this.optional(element) || false);
    // verificando data
    var data = value;
    var dia = data.substr(0, 2);
    var barra1 = data.substr(2, 1);
    var mes = data.substr(3, 2);
    var barra2 = data.substr(5, 1);
    var ano = data.substr(6, 4);
    if (data.length != 10 || barra1 != "/" || barra2 != "/" || isNaN(dia) || isNaN(mes) || isNaN(ano) || dia > 31 || mes > 12) return (this.optional(element) || false);
    if ((mes == 4 || mes == 6 || mes == 9 || mes == 11) && dia == 31) return (this.optional(element) || false);
    if (mes == 2 && (dia > 29 || (dia == 29 && ano % 4 != 0))) return (this.optional(element) || false);
    if (ano < 1900) return (this.optional(element) || false);
    return (this.optional(element) || true);
}, "Informe uma data válida"); 
                   
$( "#myform" ).validate({
  rules: {
    data: {
      required: true,
      dateBR: true
    }
  }
});
</script>

</body></html>

JsFiddle Example

    
08.10.2015 / 16:36
3

Angular does not offer any type of function to validate dates, at least not that I know of, but there are several policies that do this.

Alternatively there is the javascript library Moment.js ( link ) that offers a range of methods for working with dates.

In addition, you can use some lib of datepicker as reminded by @Techies, follow the example of the angular directive provided by it: link or Jquery-UI datepicker: link

    
08.10.2015 / 16:19
0

The function to validate dates in javascript follows.

if(validateDate("10/01/1985"))
    console.log("OK");
else
    console.log("ERRO");

function validateDate(data) {
        // Ex: 10/01/1985
        var regex = "\d{2}/\d{2}/\d{4}";
        var dtArray = data.split("/");

        if (dtArray == null)
            return false;

        // Checks for dd/mm/yyyy format.
        var dtDay= dtArray[0];
        var dtMonth = dtArray[1];
        var dtYear = dtArray[2];

        if (dtMonth < 1 || dtMonth > 12)
            return false;
        else if (dtDay < 1 || dtDay> 31)
            return false;
        else if ((dtMonth==4 || dtMonth==6 || dtMonth==9 || dtMonth==11) && dtDay ==31)
            return false;
        else if (dtMonth == 2)
        {
            var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
            if (dtDay> 29 || (dtDay ==29 && !isleap))
                return false;
        }
        return true;
    }
    
25.10.2017 / 22:34