3
\$\begingroup\$

I need to set date and time (12 hours 0 minutes) via Angular UI DatePicker Popup.

plunker


I had two issues:

1. When page was loaded:

  • Input had value 17-March-2017 12:00:00.000. It's right.

  • But Selected date was: "2017-03-17T14:57:51.080Z". It's not true, not 12:00.


2. When I changed date via button:

  • Input view was 24-March-2017 12:00:00.000

  • Selected date was: "2017-03-24T09:00:00.000Z"


I solved both issues this way:

  • I added defTime directive with formatters and parsers for input element;
  • I added time service to set 12 hours.
    If I use ng-model-options="{timezone: 'utc'}" attribute in input, I don't need to subtract TimezoneOffset from Date differently for view (formatter) and model (parser) (Compare plunker ver.1 and ver.2).

In ver.1 (without ng-model-options attribute):

  • subtracting TimezoneOffset hours for $parsers;
  • subtracting 0 hours for $formatters.


Could you offer a better solution?
Thanks.

var app = angular.module('ui.bootstrap.demo', ['ui.bootstrap']);

app.controller('DatepickerPopupDemoCtrl', function ($scope, time) {
  $scope.dt = time.getDefault(new Date());
});

app.directive('defTime', function (time) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      ngModel.$parsers.push(time.getDefault);
      ngModel.$formatters.push(time.getDefault);
    }
  }
});

app.service('time', function () {
  return {
    getDefault: getDefault
  }
  
function getDefault(dateObj){
  var tzOffset = new Date().getTimezoneOffset() / 60;
  var hoursTZ = 12 - tzOffset;

  return new Date(new Date(dateObj).setHours(hoursTZ, 0, 0, 0));
}
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>

<div ng-app="ui.bootstrap.demo">
  <div ng-controller="DatepickerPopupDemoCtrl">
    <pre>Selected date is: <em>{{dt}}</em></pre>
  
    <h4>Popup</h4>
    <div class="row">
      <div class="col-md-6">
        <p class="input-group">
          <input def-time
                type="text" 
                class="form-control" 
                uib-datepicker-popup="dd-MMMM-yyyy HH:mm:ss.sss"
                ng-model-options="{timezone: 'utc'}"
                ng-model="dt" 
                is-open="opened"/>
          <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="opened = !opened">
              <i class="glyphicon glyphicon-calendar"></i>
            </button>
          </span>
        </p>
      </div>
    </div>
  </div>
</div>

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.