Voici quelque chose de vraiment soigné et simple (du moins je crois que oui :)) et ne nécessite aucune manipulation de la date pour être cloné ou surcharger l'une des fonctions natives du navigateur comme toJSON (référence: Comment JSON stringifier une date javascript et préserver le fuseau horaire , courtise Shawson)
Passez une fonction de remplacement à JSON.stringify qui stringifie les choses à votre guise !!! De cette façon, vous n'avez pas à faire des différences d'heures et de minutes ou toute autre manipulation.
J'ai mis dans console.logs pour voir les résultats intermédiaires afin que ce qui se passe et comment fonctionne la récursivité soit clair. Cela révèle quelque chose qui mérite d'être remarqué: le paramètre de valeur à remplacer est déjà converti au format de date ISO :). Utilisez cette [touche] pour travailler avec les données originales.
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.
*/
2009-09-28T10:00:00Z
ne représente pas le même moment dans le temps queMon Sep 28 10:00:00 UTC+0200 2009
. LeZ
dans une date ISO 8601 signifie UTC, et 10 heures en UTC est un moment différent de 10 heures en +0200. Ce serait une chose de vouloir que la date soit sérialisée avec le bon fuseau horaire, mais vous nous demandez de vous aider à la sérialiser en une représentation qui est sans équivoque, objectivement fausse .