Mes objets de date en JavaScript sont toujours représentés par UTC +2 en raison de l'endroit où je me trouve. Donc comme ça
Mon Sep 28 10:00:00 UTC+0200 2009
Problème fait un JSON.stringify
Convertit la date ci-dessus en
2009-09-28T08:00:00Z (notice 2 hours missing i.e. 8 instead of 10)
Ce dont j'ai besoin, c'est que la date et l'heure soient respectées, mais ce n'est pas le cas.
2009-09-28T10:00:00Z (this is how it should be)
Fondamentalement, j'utilise ceci:
var jsonData = JSON.stringify(jsonObject);
J'ai essayé de passer un paramètre de remplacement (second 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 date, mais ceux-ci ne me donnent pas ce que je veux non plus.
Quelqu'un peut-il m'aider?
Récemment, j'ai rencontré le même problème. Et cela 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);
JSON utilise le Date.prototype.toISOString
fonction qui ne représente pas l'heure locale - elle représente l'heure en UTC non modifié - si vous regardez votre sortie de date, vous pouvez voir que vous êtes à UTC + 2 heures. C'est pourquoi la chaîne JSON change de deux heures, mais si cela permet à la même heure d’être correctement représentée sur plusieurs fuseaux horaires.
Pour mémoire, rappelez-vous que le dernier "Z" de "2009-09-28T08: 00: 00Z" signifie que l'heure est bien en UTC.
Voir http://en.wikipedia.org/wiki/ISO_8601 pour plus de détails.
Voici une autre réponse (et personnellement, je pense que c'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 écraser la fonction toJson dans le cas d’une Date utilisant Prototype comme ceci:
Date.prototype.toJSON = function(){
return Util.getDateTimeString(this);
};
Dans mon cas, Util.getDateTimeString (this) renvoie une chaîne comme celle-ci: "2017-01-19T00: 00: 00Z"
date.toJSON () imprime la date UTC dans une chaîne formatée (le décalage est donc ajouté lors de la conversion au format JSON).
date = new Date();
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();
J'ai contourné ce problème en utilisant le moment.js
bibliothèque (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 le flatpickr.min.js
bibliothèque. L'heure de la création de l'objet JSON résultant correspond à l'heure locale fournie mais au sélecteur de date.
vous pouvez utiliser moment.js pour formater avec l'heure locale:
Date.prototype.toISOString = function () {
return moment(this).format("YYYY-MM-DDTHH:mm:ss");
};
Habituellement, vous souhaitez que les dates soient présentées à chaque utilisateur dans son heure locale.
c'est pourquoi nous utilisons GMT (UTC).
Utilisez Date.parse (jsondatestring) pour obtenir la chaîne d’heure locale.
sauf si vous voulez indiquer votre heure locale à chaque visiteur.
Dans ce cas, utilisez la méthode d'Anatoly.
Je rencontre un peu ce problème avec les produits traditionnels, où ils ne travaillent que sur la côte est des États-Unis et ne stockent pas les dates au format UTC, il s’agit uniquement de données EST. Je dois filtrer les dates en fonction de la saisie de l'utilisateur dans le navigateur, il faut donc que la date soit passée en heure locale au format JSON.
Juste pour élaborer sur cette solution déjà affichée - voici 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();
Donc, si j'ai bien compris, cela va aller de l'avant et soustraire le temps (en millisecondes (donc 60000)) à partir de la date de début en fonction du décalage du fuseau horaire (renvoyé minutes) - en prévision de l'ajout du temps que toJSON () va ajouter.
Solution prête à l'emploi pour forcer JSON.stringify
ignorer les fuseaux horaires:
// 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 soigné et simple (au moins, je crois bien :)) et ne nécessite aucune manipulation de la date à cloner ni surcharger aucune des fonctions natives du navigateur comme toJSON (référence: Comment JSON codifier une date javascript et préserver le fuseau horaire) , courtie Shawson)
Transmettez une fonction de remplacement à JSON.stringify qui renforce le contenu à votre convenance !!! De cette façon, vous n'avez pas à faire de diffs heure et minute ou d'autres manipulations.
J'ai mis dans console.logs pour voir les résultats intermédiaires, ainsi il est clair ce qui se passe et comment fonctionne la récursivité. Cela révèle quelque chose qui mérite d'être signalé: la valeur param à remplacer est déjà convertie au format de date ISO :). Utilisez cette [touche] pour travailler avec les 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.
*/
Tout se résume à savoir si le serveur de votre serveur est indépendant du fuseau horaire ou non. Si ce n'est pas le cas, vous devez supposer que le fuseau horaire du serveur est identique à celui du client, ou transférer des informations sur le fuseau horaire du client et les inclure également dans les calculs.
un exemple basé sur le backend de 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 ne souhaitez pas implémenter correctement la logique de fuseau horaire.
Au lieu de toJSON
, vous pouvez utiliser la fonction format qui donne toujours la date et l'heure correctes + GMT
C'est l'option d'affichage la plus robuste. Il prend une chaîne de jetons et les remplace par les valeurs correspondantes.