web-dev-qa-db-fra.com

Comment envoyer une valeur de datepicker AngularStrap sans fuseau horaire?

Je me demande s'il est possible d'utiliser le sélecteur de date d'AngularStrap sans qu'il conserve les informations de fuseau horaire de l'utilisateur local. Dans notre application, nous voulons gérer les objets Contract qui ont une date d'expiration.

Lors de l'ajout ou de la modification de l'objet de contrat, un champ de sélection de date permet de sélectionner la date. La chose suivante se produit:

  1. L'utilisateur sélectionne la date (par exemple 2013-10-24)
  2. Angular lie l'objet de date javascript au champ ng-model
  3. L'objet date lié se trouve dans le fuseau horaire de l'utilisateur (par exemple GMT + 3)
  4. L'utilisateur soumet le formulaire
  5. La date est envoyée au serveur en utilisant le service $ http d'Angular

À l'étape 5, la date est convertie au format UTC. La date sélectionnée était GMT + 3 2013-10-24 à minuit, mais la conversion UTC change la date en 2013-10-23 à 21h.

Comment empêcher la conversion ou utiliser des dates UTC pendant tout le processus? Nous ne voulons pas que la date du contrat change en fonction du fuseau horaire local de l'utilisateur. Au lieu de cela, nous voulons que la date soit toujours le 2013-10-24, quel que soit le fuseau horaire.

Notre solution actuelle consistait à apporter de petites modifications à la bibliothèque AngularStrap afin que la date ne change pas lors de l'envoi au serveur.

Si nous pouvions obtenir le fuseau horaire sélectionné par l'utilisateur sur le serveur, nous pourrions y effectuer une autre conversion, mais le serveur ne dispose pas de ces informations.

Toutes les idées sont appréciées!

41
Janne

Le problème n'est pas AngularStrap. C'est juste comment les dates javascript fonctionnent et comment JSON les formate pour la transmission. Lorsque vous transformez un objet de date javascript en une chaîne JSON, il formate la chaîne en UTC.

Par exemple, je suis en Utah et il est maintenant 07h41 le 2013-10-24. Si je crée une nouvelle date javascript et l'imprime sur la console, elle dira:

Thu Oct 24 2013 07:41:19 GMT-0600 (MDT)

Si je stringifie cette même date (en utilisant JSON.stringify(date), j'obtiens:

"2013-10-24T13:41:47.656Z"

que vous pouvez voir n'est pas dans mon fuseau horaire actuel, mais est en UTC. La conversion a donc lieu juste avant l'envoi du formulaire au serveur lors de sa conversion d'un objet javascript en une chaîne JSON.

La façon la plus simple de le faire serait de simplement changer la date en une chaîne de votre choix avant d'envoyer la date au serveur. Ainsi, au lieu de laisser JSON changer la date en UTC, (en supposant que vous ne vous souciez pas de l'heure de la journée), vous pouvez simplement faire quelque chose comme ceci:

var dateStrToSend = $scope.date.getUTCFullYear() + '-' + ($scope.date.getUTCMonth() + 1) +  '-' + $scope.date.getUTCDate();

Cela vous donnera une chaîne basée sur UTC qui ressemble à '2013-10-24' Et vous pourrez ensuite l'envoyer au serveur, au lieu du format JSON qui inclut les informations d'heure. J'espère que cela aide.

MISE À JOUR: Comme l'a dit @Matt Johnson, il y a deux façons de le faire. Vous avez dit: How could we prevent the conversion, or use UTC dates during the whole process?. Si vous souhaitez utiliser UTC, utilisez mon explication ci-dessus. Si vous voulez simplement "empêcher la conversion", vous pouvez utiliser ce qui suit:

var dateStrToSend = $scope.date.getFullYear() + '-' + ($scope.date.getMonth() + 1) +  '-' + $scope.date.getDate();
46
tennisgent

Un peu tard mais j'ai passé mon après-midi là-dessus et quelqu'un pourrait le trouver utile.

Une autre façon de procéder de manière déclarative consiste à utiliser les attributs dateType, dateFormat et modelDateFormat. Définissez-les dans la configuration ou le HTML, par exemple

angular.module('app').config(function ($datepickerProvider) {
    angular.extend($datepickerProvider.defaults, {
        dateFormat: 'dd-MMMM-yyyy',
        modelDateFormat: "yyyy-MM-ddTHH:mm:ss",
        dateType: "string"
    });
});

DateFormat est le format auquel la date sera affichée à l'utilisateur dans le sélecteur de date tandis que modelDateFormat est le format dans lequel il sera converti avant d'être lié à votre modèle.

J'avais également des valeurs par défaut provenant du serveur dont j'avais besoin d'être lié au datepicker au chargement de la page. J'ai donc dû mettre à jour le format des dates sérialisées du serveur en JSON pour correspondre au modelDateFormat. J'utilise l'API Web, j'ai donc utilisé ce qui suit.

var jsonSettings = Formatters.JsonFormatter.SerializerSettings;
jsonSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss";
16
Bradley MIller

La "méthode angulaire" consiste à utiliser le service $ filter pour formater la date renvoyée par le sélecteur de date.

Exemple (HTML):

{{inpDate | date: 'dd-MM-yyyy'}}

Exemple (JS):

$scope.processDate = function(dt) {
return $filter('date')(dt, 'dd-MM-yyyy');
}

Plunker ici

11
WeNeigh