Eric Lu

AngularJS Date Range Picker in Neutral Timezone

November 09, 2015 | 3 Minute Read

Previously, I blogged about a way to store dates or timings using the Angular UI Bootstrap widgets in a timezone-neutral manner.

In this previous blog article, I presented a way to store dates and timings in a timezone-neutral manner using the popular Angular UI Bootstrap widgets. In order to extend the functionality of my website, I had to allow the selection of date ranges, but I was looking for a AngularJS widget that is much more user friendly than selecting 2 different dates using standard datepickers. Eventually, I stumbled upon https://github.com/fragaria/angular-daterangepicker which boasts sufficiently powerful features, though lacking in timezone support again.

Why do we need timezone support?

To cut the chase short, I will suggest that you check out my previous post about the need for timezone support.

How to convert the dates to a neutral timezone using the angular-daterangepicker widget?

If you read my previous post, you will notice that the code in that article could probably serve the same function here. However, there’s a caveat. The angular-daterangepicker widget stores dates (or timings) internally as MomentJS objects by utilizing the MomentJS library, and MomentJS objects are different from standard Date objects.

So below here is the revised code to support the angular-daterangepicker widget. The part that is revised is mainly the parser function.

angular.module('app')
  .directive('daterangepickerNeutralTimezone', function() {
    return {
      restrict: 'A',
      priority: 1,
      require: 'ngModel',
      link: function (scope, element, attrs, ctrl) {
        ctrl.$formatters.push(function (value) {
          if (value.startDate && value.endDate) {
            var startDate = new Date(Date.parse(value.startDate));
            startDate = new Date(startDate.getTime() + (60000 * startDate.getTimezoneOffset()));
            var endDate = new Date(Date.parse(value.endDate));
            endDate = new Date(endDate.getTime() + (60000 * endDate.getTimezoneOffset()));
            return {startDate: startDate, endDate: endDate};
          } else {
            return value;
          }
        });

        ctrl.$parsers.push(function (value) {
          if (value.startDate && value.endDate) {
            var startDate = value.startDate.add(60000 * value.startDate.utcOffset());
            var endDate = value.endDate.add(60000 * value.endDate.utcOffset());
            return {startDate: startDate, endDate: endDate};
          } else {
            return value;
          }
        });
      }
    };
  });

And again, you would use the directive together with the angular-daterangepicker widget like this:

<input date-range-picker class="form-control date-picker" type="text" ng-model="range" min="minDate" daterangepicker-neutral-timezone />

Similarly, you can then display the stored dates using the AngularJS date filter adjusted to the UTC timezone.

{{ range.startDate | date:null:'UTC' }} - {{ range.endDate | date:null:'UTC' }}