Question

Mes objets de date en JavaScript sont toujours représentés par UTC +2 à cause de l'endroit où je me trouve. Par conséquent, comme cela

Mon Sep 28 10:00:00 UTC+0200 2009

Le problème est de faire une JSON.stringify convertit la date ci-dessus pour

2009-09-28T08:00:00Z  (notice 2 hours missing i.e. 8 instead of 10)

Ce que je dois est la date et l'heure d'être honoré, mais ce n'est pas, par conséquent, il doit être

2009-09-28T10:00:00Z  (this is how it should be)

En fait, j'utilise ceci:

var jsonData = JSON.stringify(jsonObject);

I essayé de faire passer un paramètre de remplacement (deuxième paramètre sur stringify), mais le problème est que la valeur a déjà été traitée.

J'ai aussi essayé d'utiliser toString() et toUTCString() sur l'objet de la date, mais ceux-ci ne me donne pas ce que je veux soit ..

Quelqu'un peut-il me aider?

Était-ce utile?

La solution

Récemment, j'ai couru dans le même problème. Et il a été résolu en utilisant le code suivant:

x = new Date();
let hoursDiff = x.getHours() - x.getTimezoneOffset() / 60;
let minutesDiff = (x.getHours() - x.getTimezoneOffset()) % 60;
x.setHours(hoursDiff);
x.setMinutes(minutesDiff);

Autres conseils

JSON utilise la fonction Date.prototype.toISOString qui ne représente pas l'heure locale - il représente le temps en UTC non modifié - si vous regardez votre sortie de date, vous pouvez voir que vous êtes à UTC + 2 heures, ce qui explique pourquoi les changements de chaîne JSON de deux heures, mais si cela permet en même temps d'être représenté correctement sur plusieurs fuseaux horaires.

Juste pour mémoire, rappelez-vous que le dernier « Z » dans « 2009-09-28T08: 00: 00Z ». Signifie que le temps est en effet UTC

Voir http://en.wikipedia.org/wiki/ISO_8601 pour plus de détails.

Voici une autre réponse (et je pense personnellement qu'il est plus approprié)

var currentDate = new Date(); 
currentDate = JSON.stringify(currentDate);

// Now currentDate is in a different format... oh gosh what do we do...

currentDate = new Date(JSON.parse(currentDate));

// Now currentDate is back to its original form :)

Je suis un peu en retard, mais vous pouvez toujours remplacer la fonction toJson en cas d'une date en utilisant Prototype comme ceci:

Date.prototype.toJSON = function(){
    return Util.getDateTimeString(this);
};

Dans mon cas, Util.getDateTimeString (ce) renvoie une chaîne comme ceci: "2017-01-19T00: 00: 00Z"

date.toJSON () affiche l'UTC-date dans une chaîne formatée (ajoute donc le décalage avec elle quand le convertit au format JSON).

date = new Date();
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();

En général, vous voulez les dates à présenter à chaque utilisateur dans sa propre heure locale -

c'est pourquoi nous utilisons GMT (UTC).

Utilisez Date.parse (jsondatestring) pour obtenir la chaîne de l'heure locale,

voulez votre heure locale montré à chaque visiteur.

Dans ce cas, utilisez la méthode Anatoly.

Vous avez ce problème en utilisant la bibliothèque moment.js (la version non-fuseau horaire).

var newMinDate = moment(datePicker.selectedDates[0]);
var newMaxDate = moment(datePicker.selectedDates[1]);

// Define the data to ask the server for
var dataToGet = {"ArduinoDeviceIdentifier":"Temperatures",
                "StartDate":newMinDate.format('YYYY-MM-DD HH:mm'),
                "EndDate":newMaxDate.format('YYYY-MM-DD HH:mm')
};

alert(JSON.stringify(dataToGet));

J'utilisais la bibliothèque flatpickr.min.js. Le temps de l'objet JSON résultant créé correspond à l'heure locale fournie, mais le sélecteur de date.

vous pouvez utiliser moment.js pour formater l'heure locale:

Date.prototype.toISOString = function () {
    return moment(this).format("YYYY-MM-DDTHH:mm:ss");
};

Out-of-the-box solution pour forcer JSON.stringify ignorer timezones:

  • javascript pur (fonction de la réponse Anatoliy):

// Before: JSON.stringify apply timezone offset
const date =  new Date();
let string = JSON.stringify(date);
console.log(string);

// After: JSON.stringify keeps date as-is!
Date.prototype.toJSON = function(){
    const hoursDiff = this.getHours() - this.getTimezoneOffset() / 60;
    this.setHours(hoursDiff);
    return this.toISOString();
};
string = JSON.stringify(date);
console.log(string);

Utilisation de la bibliothèque moment.js:

const date =  new Date();
let string = JSON.stringify(date);
console.log(string);

Date.prototype.toJSON = function(){
    return moment(this).format("YYYY-MM-DDTHH:mm:ss:ms");;
};
string = JSON.stringify(date);
console.log(string);
<html>
  <header>
    <script src="https://momentjs.com/downloads/moment.min.js"></script>
    <script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.min.js"></script>
</header>
</html>

Voici quelque chose de vraiment propre et simple (moins je crois que oui :)) et ne nécessite aucune manipulation de la date à cloner ou de surcharger l'une des fonctions natives du navigateur comme toJSON (référence: Comment stringify JSON un javascript Date et préserver fuseau horaire , courtsy Shawson)

Passez une fonction de succédané à JSON.stringify que stringifies choses au contenu de votre coeur !!! De cette façon, vous ne devez pas faire diffs heures et minutes ou toute autre manipulation.

Je l'ai mis en console.logs pour voir les résultats intermédiaires il est donc clair ce qui se passe et comment récursion fonctionne. Cela révèle quelque chose digne de remarque: valeur à param est déjà succédané converti en format ISO date :). Utilisez cette [touche] pour travailler avec des données d'origine.

var replacer = function(key, value)
{
    var returnVal = value;
    if(this[key] instanceof Date)
    {
        console.log("replacer called with key - ", key, " value - ", value, this[key]); 

        returnVal = this[key].toString();

        /* Above line does not strictly speaking clone the date as in the cloned object 
         * it is a string in same format as the original but not a Date object. I tried 
         * multiple things but was unable to cause a Date object being created in the 
         * clone. 
         * Please Heeeeelp someone here!

        returnVal = new Date(JSON.parse(JSON.stringify(this[key])));   //OR
        returnVal = new Date(this[key]);   //OR
        returnVal = this[key];   //careful, returning original obj so may have potential side effect

*/
    }
    console.log("returning value: ", returnVal);

    /* if undefined is returned, the key is not at all added to the new object(i.e. clone), 
     * so return null. null !== undefined but both are falsy and can be used as such*/
    return this[key] === undefined ? null : returnVal;
};

ab = {prop1: "p1", prop2: [1, "str2", {p1: "p1inner", p2: undefined, p3: null, p4date: new Date()}]};
var abstr = JSON.stringify(ab, replacer);
var abcloned = JSON.parse(abstr);
console.log("ab is: ", ab);
console.log("abcloned is: ", abcloned);

/* abcloned is:
 * {
  "prop1": "p1",
  "prop2": [
    1,
    "str2",
    {
      "p1": "p1inner",
      "p2": null,
      "p3": null,
      "p4date": "Tue Jun 11 2019 18:47:50 GMT+0530 (India Standard Time)"
    }
  ]
}
Note p4date is string not Date object but format and timezone are completely preserved.
*/

Je lance dans ce travail un peu avec des trucs existants où ils ne fonctionnent que sur la côte est des États-Unis et ne stockent pas les dates UTC, il est tout HNE. Je dois filtrer les dates basées sur l'entrée d'utilisateur dans le navigateur afin doit passer la date à l'heure locale au format JSON.

Juste pour élaborer cette solution déjà publié - ce que j'utilise:

// Could be picked by user in date picker - local JS date
date = new Date();

// Create new Date from milliseconds of user input date (date.getTime() returns milliseconds)
// Subtract milliseconds that will be offset by toJSON before calling it
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();

Alors, je crois comprendre cela ira de l'avant et soustraire le temps (en millisecondes (donc 60000) à partir de la date de départ en fonction du décalage horaire (retourne minutes) - en prévision de l'ajout de temps toJSON () va ajouter.

Tout se résume à si votre système de serveur est fuseau horaire agnostique ou non. Dans le cas contraire, vous devez supposer que le fuseau horaire de serveur est le même en tant que client, ou transférer des informations sur le fuseau horaire du client et inclure également que dans les calculs.

un exemple basé backend PostgreSQL:

select '2009-09-28T08:00:00Z'::timestamp -> '2009-09-28 08:00:00' (wrong for 10am)
select '2009-09-28T08:00:00Z'::timestamptz -> '2009-09-28 10:00:00+02'
select '2009-09-28T08:00:00Z'::timestamptz::timestamp -> '2009-09-28 10:00:00'

Le dernier est probablement ce que vous voulez utiliser dans la base de données, si vous n'êtes pas disposé appliquer correctement la logique de fuseau horaire.

Au lieu de toJSON, vous pouvez utiliser la fonction qui donne toujours la date correcte et le temps + GMT

  

Ceci est l'option d'affichage le plus robuste. Il prend une chaîne de jetons   et les remplace par leurs valeurs correspondantes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top