Actual Behavior:
What is the issue? * The timezone is not considered: date is always returned with current timezone at midnightWhat is the expected behavior?The return date is with selected timezoneCodePen (or steps to reproduce the issue): *
CodePen Demo which shows your issue: http://codepen.io/simonered/pen/KWPgNxDetails: Select the same date both with calendar and datepicker and see the resultsAngular Versions: *
Angular Version: 1.6.2Angular Material Version: 1.1.3Additional Information:
Browser Type: * IndifferentBrowser Version: * OS: *Stack Traces:This is a huge issue for our application, and I don't know any workaround besides "don't use angular-md". I don't expect it to get fixed, though, considering the bug is probably considered something of a "feature" at this point. Would break old applications that rely on the bug...
I ended up writing a custom directive amending the returned date, to use within md-calendar. It's a good workaround (imho :smile: ), but I still think the bug has to be fixed.
myApp.directive('tzDate', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$viewChangeListeners.push(function(){
if (ngModelCtrl.$modelValue && angular.isDate(ngModelCtrl.$modelValue)) {
var offset = attrs.tzDate;
offset && $parse(attrs.ngModel).assign(scope, moment(ngModelCtrl.$modelValue).utcOffset(offset, true).toDate());
}
});
}
};
});
html
<md-calendar ng-model="date" tz-date="+02:00"></md-calendar>
Nice! I ended up writing a component (that doesn't rely on moment, although I think moment is probably unnecessary with your approach as well)
(function () {
'use strict';
angular.module('app.widgets').component('datePicker', {
templateUrl: 'path/to/template.html',
controller: DatePickerController,
bindings: {
minDate: '<?',
maxDate: '<?',
required: '<?',
placeholder: '<?',
currentView: '<?',
name: '<?',
initialDate: '<?',
onChange: '&',
ariaLabel: '<?'
}
});
function DatePickerController() {
var vm = this;
if (!vm.initialDate) {
vm.date = null;
} else {
// outer date is UTC
// convert to local tim
vm.date = new Date(vm.initialDate.getTime() + 60000 * vm.initialDate.getTimezoneOffset());
}
vm.update = update;
function update(date) {
// inner date is local time
// convert to UTC to pass back up
var utcDate = new Date(date.getTime() - 60000 * date.getTimezoneOffset());
vm.onChange({ date: utcDate });
}
}
}());
<md-datepicker
name="{{$ctrl.name}}"
ng-required="$ctrl.required"
md-min-date="$ctrl.minDate"
md-max-date="$ctrl.maxDate"
md-current-view="{{$ctrl.currentView}}"
ng-model="$ctrl.date"
layout
md-placeholder="{{$ctrl.placeholder}}"
ng-change="$ctrl.update($ctrl.date)"
aria-label="$ctrl.ariaLabel"
></md-datepicker>
<date-picker name="'someDate'" required="true" min-date="ctrl.minDate"
initial-date="ctrl.date"
on-change="ctrl.date = date"
placeholder="'Placeholder'"
></date-picker>
I'm a React fan so I reached for the component when I saw this problem.
I can see the difference in behavior and it needs to be fixed. I've updated the CodePen for 1.1.5 and the issue is still there.
This is needed so that the md-datepicker's calendar panel can be in sync with the md-datepicker's input. That issue is tracked in https://github.com/angular/material/issues/10598.
A similar fix was made for the md-datepicker, it may be helpful to review when making this fix.
any progress?
@Splaktar
DatePickerCtrl.prototype.onExternalChange = function(value) {
var timezone = this.$mdUtil.getModelOption(this.ngModelCtrl, 'timezone');
this.date = !value ? value : new Date(this.locale.formatDate(value, timezone)); //changed part
this.inputElement.value = this.locale.formatDate(value, timezone);
this.mdInputContainer && this.mdInputContainer.setHasValue(!!value);
this.resizeInputElement();
this.updateErrorState();
};
works for me
@gaby64 I haven't had a chance to get back to this. I've been focused on P1 issues. If you want to submit a PR to fix this, I would be happy to review it and try to get it merged.
Opened PR 🧙♂️ https://github.com/angular/material/pull/11906 ✨ for this issue.
Most helpful comment
Nice! I ended up writing a component (that doesn't rely on moment, although I think moment is probably unnecessary with your approach as well)
I'm a React fan so I reached for the component when I saw this problem.