5

I am trying to use ui-bootstrap datepicker binded to unix timestamp datas.

to do so, i would like to use this directive which transforms the unix timestamp to a javascript date from ng-model.

here is the code (plunker)

<div ng-model="date" date-format>
    <datepicker min="minDate" show-weeks="false"></datepicker>
</div>

and the directive

  .directive('dateFormat', function() {
        return {
              require: 'ngModel',
              link: function(scope, element, attr, ngModelCtrl) {
                    ngModelCtrl.$formatters.unshift(function(timestamp) {
                          if (timestamp) return new Date( timestamp * 1000 );
                          else return "";
                    });
                    ngModelCtrl.$parsers.push(function(date) {
                          if (date instanceof Date) return Math.floor( date.getTime() / 1000 ); 
                          else return "";
                    });
              }
        };
  })

it's possible to select a date. The unix timestamp is correct but then, the calendar switches to 1970…

is there a solution to make this work and use ui bootstrap's datepicker with unix timestamp datas ?

Community
  • 1
  • 1
François Romain
  • 13,617
  • 17
  • 89
  • 123

2 Answers2

3

It's kinda late, but I also had this problem - I don't want to keep additional value in my model just for datepicker/timepicker. Followed this great tutorial on ngModelController by Christopher Nadeau

This works in AngularJS 1.2.16:

.directive('timestampFormat', function() {
    // Directive that converts timestamp back and forth from
    // seconds to Date object
    return {
        scope: true, // isolated scope
        require: 'ngModel',
        link: function(scope, element, attr, ngModelCtrl) {

            ngModelCtrl.$formatters.push(function (modelValue) {
                // returns $viewValue
                return {
                    timestamp: (modelValue ? new Date(modelValue*1000) : "")
                };
            });

            scope.$watch('timestamp', function () {
                ngModelCtrl.$setViewValue({ timestamp: scope.timestamp });
            });

            ngModelCtrl.$parsers.push(function (viewValue) {
                // returns $modelValue
                if (viewValue.timestamp instanceof Date) return Math.floor( viewValue.timestamp.getTime() / 1000 );
                else return "";
            });

            ngModelCtrl.$render = function () {
                // renders timestamp to the view.
                if (!ngModelCtrl.$viewValue) ngModelCtrl.$viewValue = { timestamp: ""};
                scope.timestamp = ngModelCtrl.$viewValue.timestamp;
            };
        }
    };
});

Now in view you can access it as a timestamp variable.

<div ng-model="yourModelValue" timestamp-format> 
  {{timestamp}}
  <timepicker ng-model="timestamp" ...>
Plyto
  • 741
  • 1
  • 9
  • 18
0

your don't need multiplied and divided

link: function(scope, element, attr, ngModelCtrl) {
          ngModelCtrl.$formatters.unshift(function(timestamp) {
            if (timestamp) {
              var date = new Date( timestamp );
              console.log('timestamp to date: ', date); 
              return date;
            }   else return "";
          });
          ngModelCtrl.$parsers.push(function(date) {
            if (date instanceof Date) {
              timestamp = date.getTime();
              console.log('date to timestamp: ', timestamp);
              return timestamp; 
                } else return "";
          });
        }
Kain
  • 273
  • 1
  • 6
  • if i do this the timestamp conversion is not correct anymore. (check here : [unix timestamp conversion](http://www.unixtimestamp.com/) – François Romain Nov 18 '13 at 08:53