HTML codes:
<!DOCTYPE html>
<html>
  <head>
    <script src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
    <script src="https://code.angularjs.org/1.3.15/angular-messages.js"></script>
    <script src="script.js"></script>
  </head>
  <body ng-app="validationExample">
    <div ng-controller="MyCtrl as vm">
      <form name="myForm" novalidate="" ng-submit="vm.submitted(myForm, vm.input)">
        <span class="input-label">Start Date</span> 
        <input type="date" name="startDate" ng-model="vm.input.startDate" required />
        <span ng-messages="myForm.startDate.$error" ng-messages-include="errors-template.html"></span>
        <br />       
        <span class="input-label">End Date</span> 
        
        <input type="date" name="endDate" ng-model="vm.input.endDate" start-date="{{vm.input.startDate.yyyymmdd()}}" compare-with-start-date />
        <span ng-messages="myForm.endDate.$error" ng-messages-include="errors-template.html"></span>
        <br />             
        <button>submit</button>
      </form>
    </div>
    
    <!-- error messages template -->
    <script id="errors-template.html" type="text/ng-template">
        <span ng-message="required">* required!</span>
        <span class="form-error" ng-message="checkEndDate">* end date cannot be earlier than start date</span>
    </script>
  </body>
</html>
JavaScript codes:
var myApp = angular.module('validationExample', ['ngMessages'])
myApp.controller('MyCtrl', [function () {
    var vm = this;
    vm.submitted = function(form, input) {
      if(form.$valid) {
        alert('submitted');
      }
    }
} ]);
myApp.directive("compareWithStartDate", function () {
    return {
        restrict: "A",
        require: "?ngModel",
        link: function (scope, element, attributes, ngModel) {
            validateEndDate = function (endDate, startDate) {
                if (endDate && startDate) {
                    startDate = new Date(startDate);
                    startDate.setHours(0, 0, 0, 0);
                    endDate = new Date(endDate);
                    endDate.setHours(0, 0, 0, 0);
                    return endDate >= startDate;
                }
                else {
                    return true;
                }
            }
            // use $validators.validation_name to do the validation
            ngModel.$validators.checkEndDate = function (modelValue) {
                var startdate = Date.parse(attributes.startDate);
                var enddate = modelValue;
                return validateEndDate(enddate, startdate);
            };
            
            // use $observe if we need to keep an eye for changes on a passed value
            attributes.$observe('startDate', function (value) {
                var startdate = Date.parse(value);
                var enddate = Date.parse(ngModel.$viewValue);
                
                // use $setValidity method to determine the validation result 
                // the first parameter is the validation name, this name is the same in ng-message template as well
                // the second parameter sets the validity (true or false), we can pass a function returning a boolean
                ngModel.$setValidity("checkEndDate", validateEndDate(enddate, startdate));
            });
        }
    };
});
// function to parse date time object into yyyy-mm-dd format string
Date.prototype.yyyymmdd = function () {
    var yyyy = this.getFullYear().toString();
    var mm = (this.getMonth() + 1).toString(); // getMonth() is zero-based         
    var dd = this.getDate().toString();
    return yyyy + '-' + (mm[1] ? mm : "0" + mm[0]) + '-' + (dd[1] ? dd : "0" + dd[0]);
};
See the example in Plunker.
 
 
