angularjs - Angular UI DatePicker ajustando para la zona horaria
timezone angular-ui (5)
Hace un tiempo tuve un problema muy similar: quería almacenar las fechas locales en el lado del servidor (es decir, solo aaaa-mm-dd y sin información timezome / time) pero dado que Angular Bootstrap Datepicker utiliza el objeto JavaScript Date esto no fue posible (serializa a una cadena de fecha y hora UTC en el JSON como descubrió usted mismo).
Resolví el problema con esta directiva: https://gist.github.com/weberste/354a3f0a9ea58e0ea0de
Esencialmente, estoy reformateando el valor cada vez que se selecciona una fecha en el datepicker (este valor, una cadena formateada aaaa-mm-dd, se almacenará en el modelo) y siempre que se acceda al modelo para llenar la vista, necesito envuélvalo en un objeto Date nuevamente para que datepicker lo maneje correctamente.
Tengo una fecha almacenada como una fecha en SQL Server. La fecha muestra 4/24/2014 cuando realizo consultas en SQL. Eso es correcto. La fecha se lleva correctamente al lado del cliente en UTC. Para editar esa fecha, estamos usando Angular UI DatePicker. El DatePicker está ajustando esa fecha en función de mi zona horaria local, por lo que siempre está desactivada por un día.
Puedo ver que está sucediendo. Si estuviéramos editando un DateTime en lugar de una fecha, entonces sería correcto ajustar la zona horaria. Sin embargo, en este caso, solo tengo una Fecha, así que no me importa la zona horaria y solo quiero editar la fecha tal como estaba en la base de datos.
Puedo verificar que se está ajustando para la zona horaria. Si cambio la zona horaria en mi máquina Windows para que sea UTC, entonces el DatePicker muestra la fecha correcta.
Entonces, la pregunta es, ¿hay alguna manera de decirle al DatePicker que apague los ajustes de la zona horaria y solo administre las fechas en formato UTC para que funcione con una fecha SQL en lugar de una fecha y hora SQL?
La directiva Hope below te es útil
app.directive(''datetimepickerNeutralTimezone'', function () {
return {
restrict: ''A'',
priority: 1,
require: ''ngModel'',
link: function (scope, element, attrs, ctrl) {
ctrl.$formatters.push(function (value) {
if (typeof value === "undefined") {
var date = new Date();
//date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
return date;
} else {
var date = new Date(Date.parse(value));
//date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
return date;
}
});
ctrl.$parsers.push(function (value) {
var date = new Date(value.getTime() - (60000 * value.getTimezoneOffset()));
return date;
});
}
};
});
app.directive(''timepickerNeutralTimezone'', function () {
return {
restrict: ''A'',
priority: 1,
require: ''ngModel'',
link: function (scope, element, attrs, ctrl) {
ctrl.$formatters.push(function (value) {
if (typeof value === "undefined") {
} else {
var date = new Date(Date.parse(value));
date = new Date(date.getTime() + (60000 * date.getTimezoneOffset()));
return date;
}
});
ctrl.$parsers.push(function (value) {
var date = new Date(value.getTime() - (60000 * value.getTimezoneOffset()));
return date;
});
}
};
});
La solución se encuentra aquí: https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205
El problema de la zona horaria es fijo.
Puedes usar:
ng-model-options="{timezone: ''utc''}"
Para obtener un datepicker sin cálculo de zona horaria.
EDITAR: Esta solución no funciona desde la versión 2.x, sin embargo, estuvo perfectamente bien hasta entonces. No pude encontrar una solución y todavía estoy usando la versión 1.3.3.
EDIT 2: Como Sébastien Deprez señaló en los comentarios a continuación, esto se ha corregido en la versión 2.3.1 . Acabo de probarlo y funciona muy bien.
<input
uib-datepicker-popup
ng-model="$ctrl.myModel"
ng-model-options="{timezone: ''utc''}">
Primero, me gustaría señalar que el seleccionador de fechas localizado de bootstrap es estúpido e inútil, nadie necesita algo como esto, todo lo que realmente quieres es una fecha aaaa-MM-dd, no veo sentido en localizar una fecha en la que no sepas necesito tiempo
No trato de inclinar la parte del cliente para que se ajuste a la zona horaria del servidor, eso es excesivo y no funciona. Lo que hago en cambio es dejar que el usuario trabaje en su zona horaria y formatee la fecha antes de enviarla al servidor de esta manera:
fields.date = dateFilter(trans.date, ''MM/dd/yy'');
Esto garantiza que todo lo que el usuario vea en el selector de fechas que reciba en el servidor. Crucial si me preguntas. Si necesita establecer fechas mínimas y máximas, de nuevo, simplemente configúrelas en la zona horaria del usuario de la siguiente manera:
$scope.datepickerOptions.minDate = new Date(dateFilter(minDate, ''yyyy-MM-dd/'T/'00:00:00'', serverTimezone));
$scope.datepickerOptions.maxDate = new Date(dateFilter(maxDate, ''yyyy-MM-dd/'T/'00:00:00'', serverTimezone));
minDate y maxDate son fechas localizadas en el servidor y serverTimezone es el offset de la zona horaria del servidor (''+0500'' por ejemplo).
¡Espero que esto ayude!
la mejor solución es usar la biblioteca de momento.js corregir todos los errores entre la zona horaria del navegador y la zona horaria del componente