36 votes

Désérialisation des dates AJAX JSON côté client

Étant donné la représentation JSON suivante de la date :

"\/Date(1221644506800-0700)\/"

Comment désérialisez-vous cette information sous sa forme JavaScript de type date ?

J'ai essayé d'utiliser MS AJAX JavaScrioptSerializer comme indiqué ci-dessous :

Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/")

Cependant, tout ce que j'obtiens en retour est la chaîne littérale date.

0 votes

Vous utilisez peut-être jQuery ? Consultez mon article de blog pour convertir automatiquement les dates afin de ne pas avoir à le faire manuellement. erraticdev.blogspot.com/2010/12/

0 votes

Voir mes commentaires ci-dessous. Le code de votre blog échoue sur les dates avant l'époque.

30voto

Simon_Weaver Points 31141

Pour autant que vous sachiez que la chaîne est bien une date, je préfère procéder ainsi :

 new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))

0 votes

Cela a fonctionné pour moi, ma méthode ToJson sérialisait DateTimes comme "\/Date(1251795081950)\/".

2 votes

Merci. var date = new Date(parseInt(jsonDate.substr(6))); fonctionne aussi.

18voto

ESV Points 4591

Bertrand LeRoy, qui a travaillé sur ASP.NET Atlas/AJAX, décrit la conception de la sortie JavaScriptSerializer DateTime et a révélé l'origine des mystérieuses barres obliques avant et arrière. Il a fait cette recommandation :

lancez une recherche simple pour "\/Date((( \d +))\/" et remplacer par "new Date($1)" avant l'eval (mais après la validation)

Je l'ai mis en œuvre comme :

var serializedDateTime = "\/Date(1271389496563)\/";
document.writeln("Serialized: " + serializedDateTime + "<br />");

var toDateRe = new RegExp("^/Date\\((\\d+)\\)/$");
function toDate(s) {
    if (!s) {
        return null;
    }
    var constructor = s.replace(toDateRe, "new Date($1)");
    if (constructor == s) {
        throw 'Invalid serialized DateTime value: "' + s + '"';
    }
    return eval(constructor);
}

document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");

Cette réponse est très proche de la plupart des autres réponses :

  • Utilisez une RegEx ancrée comme l'a fait Sjoerd Visscher -- n'oubliez pas les ^ et $.
  • Évitez string.replace et les options 'g' ou 'i' de votre RegEx. "/Date(1271389496563)//Date(1271389496563)/" ne devrait pas du tout fonctionner.

1 votes

Une très bonne réponse.... dommage que je l'aie trouvée au bas de la liste de la question.

6 votes

Cette regex ne fonctionnera pas pour les dates antérieures à l'époque, qui ont une valeur négative. Vous avez besoin de quelque chose comme ça : /\/Date\((-?\d+)(?:-\d+)?\)\//i

11voto

Sjoerd Visscher Points 8310

Une valeur JSON est une chaîne de caractères, un nombre, un objet, un tableau, true, false ou null. Il s'agit donc simplement d'une chaîne de caractères. Il n'y a pas de manière officielle de représenter les dates en JSON. Cette syntaxe provient de l'implémentation asp.net ajax. D'autres utilisent le format ISO 8601.

Vous pouvez l'analyser comme ceci :

var s = "\/Date(1221644506800-0700)\/";
var m = s.match(/^\/Date\((\d+)([-+]\d\d)(\d\d)\)\/$/);
var date = null;
if (m)
  date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]);

0 votes

Ma méthode toJson sortait les dates sérialisées sous la forme "\/Date(1251795070160)\/", ce que votre code n'analyse pas. Je trouverai pourquoi plus tard, mais je le signale ici pour les autres.

0 votes

+1 pour avoir précisé ce que peut être une valeur JSON et que les dates n'en font pas partie, mais constituent un format personnalisé.

0 votes

Cette regex ne fonctionnera pas pour les dates antérieures à l'époque, qui ont une valeur négative. Vous avez besoin de ça : /\/Date\((-?\d+)(?:-\d+)?\)\//i

6voto

Kyle Jones Points 348

L'expression régulière utilisée dans la méthode ASP.net AJAX deserialize recherche une chaîne qui ressemble à "/Date(1234)/" (La chaîne elle-même doit en fait contenir les guillemets et les barres obliques). Pour obtenir une telle chaîne, vous devrez échapper les guillemets et les barres obliques, de sorte que le code javascript permettant de créer la chaîne ressemble à "\"\/Date(1234)\/\"".

Ça va marcher.

Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800)\\/\"")

C'est un peu bizarre, mais j'ai découvert que je devais sérialiser une date, puis sérialiser la chaîne renvoyée par celle-ci, et enfin désérialiser une fois du côté client.

Quelque chose comme ça.

Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer();
string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now)));
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true);

0 votes

Le problème de cette méthode est qu'elle ne tient pas compte du fuseau horaire : Sys.Serialization.JavaScriptSerializer.deserialize("\" \\ /Dat‌​e(1221644506800+0200‌​) \\ /\"") Le résultat sera le même que : Sys.Serialization.JavaScriptSerializer.deserialize("/\") \\ /Dat‌​e(1221644506800+0300‌​) \\ /\"")

3voto

AlexanderN Points 5805

Pour ceux qui ne veulent pas utiliser Microsoft Ajax, il suffit d'ajouter une fonction prototype à la classe string.

Par exemple

    String.prototype.dateFromJSON = function () {
    return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
};

Vous ne voulez pas utiliser eval ? Essayez quelque chose de simple comme

var date = new Date(parseInt(jsonDate.substr(6)));

Soit dit en passant, j'avais l'habitude de penser que Microsoft induisait en erreur en utilisant ce format. Cependant, la spécification JSON n'est pas très claire lorsqu'il s'agit de définir une manière de décrire les dates en JSON.

2 votes

Cette regex ne fonctionnera pas pour les dates antérieures à l'époque, qui ont une valeur négative. Vous avez besoin de ça : /\/Date\((-?\d+)(?:-\d+)?\)\//i

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X