J'ai une date stockée en tant que date dans SQL Server. La date indique 24/04/2014 lorsque je recherche en SQL. C'est exact. La date est correctement reportée côté client en UTC. Pour modifier cette date, nous utilisons le Angular UI DatePicker. Le DatePicker ajuste cette date en fonction de mon fuseau horaire local et il est donc toujours désactivé d'un jour.
Je peux voir que cela se produit. Si nous modifions un DateTime au lieu d'une Date, il serait correct d'ajuster le fuseau horaire. Cependant, dans ce cas, j'ai juste une date, donc je ne me soucie pas du fuseau horaire et je veux juste modifier la date telle qu'elle était dans la base de données.
Je peux vérifier qu'il ajuste le fuseau horaire. Si je change le fuseau horaire sur ma machine Windows pour qu'il soit UTC, le DatePicker affiche la date correcte.
Donc, la question est, existe-t-il un moyen de dire au DatePicker de désactiver les ajustements de fuseau horaire et de simplement gérer les dates au format UTC afin qu'il fonctionne avec une date SQL au lieu d'un SQL Datetime?
J'ai eu un problème très similaire il y a quelque temps: je voulais stocker les dates locales côté serveur (c'est-à-dire juste aaaa-mm-jj et aucune information de fuseau horaire/heure) mais depuis le Angular Bootstrap Datepicker utilise l'objet Date JavaScript, ce qui n'était pas possible (il se sérialise en une chaîne datetime UTC dans le JSON comme vous l'avez découvert vous-même).
J'ai résolu le problème avec cette directive: https://Gist.github.com/weberste/354a3f0a9ea58e0ea0de
Essentiellement, je reformate la valeur chaque fois qu'une date est sélectionnée sur le sélecteur de date (cette valeur, une chaîne formatée aaaa-mm-jj, sera stockée sur le modèle) et chaque fois que le modèle est accédé pour remplir la vue, je dois enveloppez-le à nouveau dans un objet Date afin que le sélecteur de date le gère correctement.
Solution trouvée ici: https://github.com/angular-ui/bootstrap/issues/4837#issuecomment-203284205
Le problème de fuseau horaire est résolu.
Vous pouvez utiliser:
ng-model-options="{timezone: 'utc'}"
Pour obtenir un sélecteur de date sans calcul de fuseau horaire.
EDIT: Cette solution ne fonctionne pas depuis la version 2.x, mais elle a parfaitement fonctionné jusque-là. Je n'ai pas trouvé de solution de contournement et j'utilise toujours la version 1.3.3.
EDIT 2: Comme Sébastien Deprez l'a souligné dans les commentaires ci-dessous, cela a été corrigé dans la version 2.3.1 . Je viens de le tester et cela fonctionne très bien.
<input
uib-datepicker-popup
ng-model="$ctrl.myModel"
ng-model-options="{timezone: 'utc'}">
Je voudrais d'abord souligner que le sélecteur de date localisé du bootstrap est stupide et inutile, personne n'a besoin de quelque chose comme ça, tout ce que vous voulez vraiment est une date aaaa-MM-jj, je ne vois aucun intérêt à localiser une date lorsque vous ne le faites pas '' t besoin de temps.
Je n'essaie pas de plier le côté client pour l'adapter au fuseau horaire du serveur, c'est exagéré et ne fonctionne pas. Ce que je fais à la place, c'est de laisser l'utilisateur travailler dans son fuseau horaire et de formater la date avant de l'envoyer au serveur comme ceci:
fields.date = dateFilter(trans.date, 'MM/dd/yy');
Cela garantit que tout ce que l'utilisateur voit dans le sélecteur de date que je reçois côté serveur. Crucial si vous me demandez. Si vous devez définir des dates min et max, encore une fois, définissez-les simplement dans le fuseau horaire de l'utilisateur comme ceci:
$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 et maxDate sont des dates localisées du serveur et le serverTimezone est le décalage du fuseau horaire du serveur ('+0500' par exemple).
J'espère que cela t'aides!
Pour moi, parce que nous utilisons une très ancienne version de la bibliothèque, et étant donné un objet expiration_date retourné par le sélecteur de date, j'ai dû trouver une solution de contournement et l'ajuster comme ça:
expiration_date.setMinutes(-expiration_date.getTimezoneOffset());
Qui définira la date demandée à sa date UTC correspondante mais toujours exprimée au format de fuseau horaire local.
Pour moi, cela a bien fonctionné. J'espère que cela peut aider quelqu'un.
L'espoir ci-dessous la directive vous est utile
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;
});
}
};
});