Only use day, month, year provided by datepicker (#11773) (#11882)

* Only use day, month, year provided by datepicker instead of moment in time
This commit is contained in:
Matt Bargar 2017-05-18 11:06:24 -04:00 committed by GitHub
parent 8e735afa70
commit d906788fb2
2 changed files with 62 additions and 6 deletions

View file

@ -455,5 +455,28 @@ describe('timepicker directive', function () {
done();
});
describe('datepicker timezone issue', function () {
it('should ignore the timezone from the datepicker because it does not respect dateFormat:tz advanced setting', function (done) {
moment.tz.setDefault('UTC');
$scope.pickFromDate(new Date('2012-02-01 12:00-05:00'));
$scope.pickToDate(new Date('2012-02-11 12:00-05:00'));
$scope.$digest();
const formattedFrom = inputs.fromInput.val();
const formattedTo = inputs.toInput.val();
expect(formattedFrom).to.be('2012-02-01 00:00:00.000');
expect(formattedTo).to.be('2012-02-11 23:59:59.999');
done();
});
after(function () {
moment.tz.setDefault('Browser');
});
});
});
});

View file

@ -77,16 +77,49 @@ module.directive('kbnTimepicker', function (quickRanges, timeUnits, refreshInter
}
});
// If we always return a new object from the getters below (pickFromDate and pickToDate) we'll create an
// infinite digest loop, so we maintain these copies to return instead.
$scope.$watch('absolute.from', function (newDate) {
_.set($scope, 'browserAbsolute.from', new Date(newDate.year(), newDate.month(), newDate.date()));
});
$scope.$watch('absolute.to', function (newDate) {
_.set($scope, 'browserAbsolute.to', new Date(newDate.year(), newDate.month(), newDate.date()));
});
// The datepicker directive uses native Javascript Dates, ignoring moment's default timezone. This causes
// the datepicker and the text input above it to get out of sync if the user changed the `dateFormat:tz` config
// in advanced settings. The text input will show the date in the user selected timezone, the datepicker will
// show the date in the local browser timezone. Since we really just want a day, month, year from the datepicker
// instead of a moment in time, we grab those individual values from the native date.
$scope.pickFromDate = function (date) {
if (!date) return $scope.absolute.from;
date.setHours(0, 0, 0, 0); // Start of day
return $scope.absolute.from = moment(date);
if (!date) return _.get($scope, 'browserAbsolute.from');
const defaultTimeZoneDate = moment({
year: date.getFullYear(),
month: date.getMonth(),
day: date.getDate(),
hour: 0,
minute: 0,
second: 0,
millisecond: 0,
});
return $scope.absolute.from = defaultTimeZoneDate;
};
$scope.pickToDate = function (date) {
if (!date) return $scope.absolute.to;
date.setHours(23, 59, 59, 999); // End of day
return $scope.absolute.to = moment(date);
if (!date) return _.get($scope, 'browserAbsolute.to');
const defaultTimeZoneDate = moment({
year: date.getFullYear(),
month: date.getMonth(),
day: date.getDate(),
hour: 23,
minute: 59,
second: 59,
millisecond: 999,
});
return $scope.absolute.to = defaultTimeZoneDate;
};
$scope.setMode = function (thisMode) {