Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit f141201

Browse files
ayakovlevghwesleycho
authored andcommitted
fix(datepicker): fix OS dependent time zone issue
- Fixes an issue with dates involving different OSes and timezones Fixes #3079
1 parent 68cac59 commit f141201

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

src/datepicker/datepicker.js

+24-7
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
128128
return arrays;
129129
};
130130

131+
// Fix a hard-reprodusible bug with timezones
132+
// The bug depends on OS, browser, current timezone and current date
133+
// i.e.
134+
// var date = new Date(2014, 0, 1);
135+
// console.log(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());
136+
// can result in "2013 11 31 23" because of the bug.
137+
this.fixTimeZone = function(date) {
138+
var hours = date.getHours();
139+
date.setHours(hours === 23 ? hours + 2 : 0);
140+
};
141+
131142
$scope.select = function( date ) {
132143
if ( $scope.datepickerMode === self.minMode ) {
133144
var dt = ngModelCtrl.$viewValue ? new Date( ngModelCtrl.$viewValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
@@ -236,10 +247,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
236247
}
237248

238249
function getDates(startDate, n) {
239-
var dates = new Array(n), current = new Date(startDate), i = 0;
240-
current.setHours(12); // Prevent repeated dates because of timezone bug
250+
var dates = new Array(n), current = new Date(startDate), i = 0, date;
241251
while ( i < n ) {
242-
dates[i++] = new Date(current);
252+
date = new Date(current);
253+
ctrl.fixTimeZone(date);
254+
dates[i++] = date;
243255
current.setDate( current.getDate() + 1 );
244256
}
245257
return dates;
@@ -341,10 +353,13 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
341353

342354
ctrl._refreshView = function() {
343355
var months = new Array(12),
344-
year = ctrl.activeDate.getFullYear();
356+
year = ctrl.activeDate.getFullYear(),
357+
date;
345358

346359
for ( var i = 0; i < 12; i++ ) {
347-
months[i] = angular.extend(ctrl.createDateObject(new Date(year, i, 1), ctrl.formatMonth), {
360+
date = new Date(year, i, 1);
361+
ctrl.fixTimeZone(date);
362+
months[i] = angular.extend(ctrl.createDateObject(date, ctrl.formatMonth), {
348363
uid: scope.uniqueId + '-' + i
349364
});
350365
}
@@ -401,10 +416,12 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
401416
}
402417

403418
ctrl._refreshView = function() {
404-
var years = new Array(range);
419+
var years = new Array(range), date;
405420

406421
for ( var i = 0, start = getStartingYear(ctrl.activeDate.getFullYear()); i < range; i++ ) {
407-
years[i] = angular.extend(ctrl.createDateObject(new Date(start + i, 0, 1), ctrl.formatYear), {
422+
date = new Date(start + i, 0, 1);
423+
ctrl.fixTimeZone(date);
424+
years[i] = angular.extend(ctrl.createDateObject(date, ctrl.formatYear), {
408425
uid: scope.uniqueId + '-' + i
409426
});
410427
}

src/datepicker/test/datepicker.spec.js

+27
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,33 @@ describe('datepicker directive', function () {
284284
expect(getTitle()).toBe('January 2014');
285285
});
286286

287+
// issue #3079
288+
describe('time zone bug', function () {
289+
290+
it('should deal with time zone bug', function() {
291+
var ctrl = element.controller('datepicker'),
292+
date = new Date('January 1, 2014');
293+
spyOn(date, 'getHours').and.returnValue(23);
294+
spyOn(date, 'setHours').and.returnValue();
295+
296+
ctrl.fixTimeZone(date);
297+
298+
expect(date.setHours).toHaveBeenCalledWith(25);
299+
});
300+
301+
it('should not change hours if time zone bug does not occur', function() {
302+
var ctrl = element.controller('datepicker'),
303+
date = new Date('January 1, 2014');
304+
spyOn(date, 'getHours').and.returnValue(0);
305+
spyOn(date, 'setHours').and.returnValue();
306+
307+
ctrl.fixTimeZone(date);
308+
309+
expect(date.setHours).toHaveBeenCalledWith(0);
310+
});
311+
312+
});
313+
287314
describe('when `model` changes', function () {
288315
function testCalendar() {
289316
expect(getTitle()).toBe('November 2005');

0 commit comments

Comments
 (0)