From 0d64aad4dd2259615b7faebf37e68491b32e16bb Mon Sep 17 00:00:00 2001 From: Wesley Cho Date: Wed, 21 Oct 2015 07:42:20 -0700 Subject: [PATCH] feat(datepicker): preserve timezone with model - Default to using the date instance for any date manipulation, allowing for the timezone to automatically be preserved Closes #4676 --- src/dateparser/dateparser.js | 13 ++++++++++--- src/datepicker/datepicker.js | 27 +++++++++----------------- src/datepicker/test/datepicker.spec.js | 26 ------------------------- 3 files changed, 19 insertions(+), 47 deletions(-) diff --git a/src/dateparser/dateparser.js b/src/dateparser/dateparser.js index a135974b43..0b4249f85e 100644 --- a/src/dateparser/dateparser.js +++ b/src/dateparser/dateparser.js @@ -183,9 +183,16 @@ angular.module('ui.bootstrap.dateparser', []) } if (isValid(fields.year, fields.month, fields.date)) { - dt = new Date(fields.year, fields.month, fields.date, - fields.hours, fields.minutes, fields.seconds, - fields.milliseconds || 0); + if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) { + dt = new Date(baseDate); + dt.setFullYear(fields.year, fields.month, fields.date, + fields.hours, fields.minutes, fields.seconds, + fields.milliseconds || 0); + } else { + dt = new Date(fields.year, fields.month, fields.date, + fields.hours, fields.minutes, fields.seconds, + fields.milliseconds || 0); + } } return dt; diff --git a/src/datepicker/datepicker.js b/src/datepicker/datepicker.js index d2f7ba55fa..7cf87593ed 100644 --- a/src/datepicker/datepicker.js +++ b/src/datepicker/datepicker.js @@ -143,17 +143,6 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst return arrays; }; - // Fix a hard-reprodusible bug with timezones - // The bug depends on OS, browser, current timezone and current date - // i.e. - // var date = new Date(2014, 0, 1); - // console.log(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()); - // can result in "2013 11 31 23" because of the bug. - this.fixTimeZone = function(date) { - var hours = date.getHours(); - date.setHours(hours === 23 ? hours + 2 : 0); - }; - $scope.select = function(date) { if ($scope.datepickerMode === self.minMode) { var dt = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : new Date(0, 0, 0, 0, 0, 0, 0); @@ -238,7 +227,6 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst var dates = new Array(n), current = new Date(startDate), i = 0, date; while (i < n) { date = new Date(current); - this.fixTimeZone(date); dates[i++] = date; current.setDate(current.getDate() + 1); } @@ -248,8 +236,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst this._refreshView = function() { var year = this.activeDate.getFullYear(), month = this.activeDate.getMonth(), - firstDayOfMonth = new Date(year, month, 1), - difference = this.startingDay - firstDayOfMonth.getDay(), + firstDayOfMonth = new Date(this.activeDate); + + firstDayOfMonth.setFullYear(year, month, 1); + + var difference = this.startingDay - firstDayOfMonth.getDay(), numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference, firstDate = new Date(firstDayOfMonth); @@ -340,8 +331,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst date; for (var i = 0; i < 12; i++) { - date = new Date(year, i, 1); - this.fixTimeZone(date); + date = new Date(this.activeDate); + date.setFullYear(year, i, 1); months[i] = angular.extend(this.createDateObject(date, this.formatMonth), { uid: scope.uniqueId + '-' + i }); @@ -395,8 +386,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst var years = new Array(range), date; for (var i = 0, start = getStartingYear(this.activeDate.getFullYear()); i < range; i++) { - date = new Date(start + i, 0, 1); - this.fixTimeZone(date); + date = new Date(this.activeDate); + date.setFullYear(start + i, 0, 1); years[i] = angular.extend(this.createDateObject(date, this.formatYear), { uid: scope.uniqueId + '-' + i }); diff --git a/src/datepicker/test/datepicker.spec.js b/src/datepicker/test/datepicker.spec.js index 0f0908b2b7..6ab0ce8596 100644 --- a/src/datepicker/test/datepicker.spec.js +++ b/src/datepicker/test/datepicker.spec.js @@ -397,32 +397,6 @@ describe('datepicker directive', function() { expect(element.html()).toBe('baz'); }); - // issue #3079 - describe('time zone bug', function() { - it('should deal with time zone bug', function() { - var ctrl = element.controller('uib-datepicker'), - date = new Date('January 1, 2014'); - spyOn(date, 'getHours').and.returnValue(23); - spyOn(date, 'setHours').and.returnValue(); - - ctrl.fixTimeZone(date); - - expect(date.setHours).toHaveBeenCalledWith(25); - }); - - it('should not change hours if time zone bug does not occur', function() { - var ctrl = element.controller('uib-datepicker'), - date = new Date('January 1, 2014'); - spyOn(date, 'getHours').and.returnValue(0); - spyOn(date, 'setHours').and.returnValue(); - - ctrl.fixTimeZone(date); - - expect(date.setHours).toHaveBeenCalledWith(0); - }); - - }); - describe('when `model` changes', function() { function testCalendar() { expect(getTitle()).toBe('November 2005');