Angular bootstrap datepicker date format does not format ng-model value

Although similar answers have been posted I'd like to contribute what seemed to be the easiest and cleanest fix to me. Assuming you are using the AngularUI datepicker and your initial value for the ng-Model does not get formatted simply adding the following directive to your project will fix the issue:

angular.module('yourAppName')
.directive('datepickerPopup', function (){
    return {
        restrict: 'EAC',
        require: 'ngModel',
        link: function(scope, element, attr, controller) {
      //remove the default formatter from the input directive to prevent conflict
      controller.$formatters.shift();
  }
}
});

I found this solution in the Github AngularUI issues and therefore all credit goes to the people over there.


The format specified through datepicker-popup is just the format for the displayed date. The underlying ngModel is a Date object. Trying to display it will show it as it's default, standard-compliant rapresentation.

You can show it as you want by using the date filter in the view, or, if you need it to be parsed in the controller, you can inject $filter in your controller and call it as $filter('date')(date, format). See also the date filter docs.


You can make use of $parsers as shown below,this solved it for me.

window.module.directive('myDate', function(dateFilter) {
  return {
    restrict: 'EAC',
    require: '?ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(viewValue) {
        return dateFilter(viewValue,'yyyy-MM-dd');
      });
    }
  };
});

HTML:

<p class="input-group datepicker" >
  <input
     type="text"
     class="form-control"
     name="name"
     datepicker-popup="yyyy-MM-dd"
     date-type="string"
     show-weeks="false"
     ng-model="data[$parent.editable.name]" 
     is-open="$parent.opened"
     min-date="minDate"
     close-text="Close"
     ng-required="{{editable.mandatory}}"
     show-button-bar="false"
     close-on-date-selection="false"
     my-date />
  <span class="input-group-btn">
    <button type="button" class="btn btn-default" ng-click="openDatePicker($event)">
      <i class="glyphicon glyphicon-calendar"></i>
    </button>
  </span>
</p>

I ran into the same problem and after a couple of hours of logging and investigating, I fixed it.

It turned out that for the first time the value is set in a date picker, $viewValue is a string so the dateFilter displays it as is. All I did is parse it into a Date object.

Search for that block in ui-bootstrap-tpls file

  ngModel.$render = function() {
    var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
    element.val(date);

    updateCalendar();
  };

and replace it by:

  ngModel.$render = function() {
    ngModel.$viewValue = new Date(ngModel.$viewValue);
    var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
    element.val(date);

    updateCalendar();
  };

Hopefully this will help :)