132 votes

Comment analyser JSON pour recevoir un objet Date en JavaScript ?

J'ai le morceau de JSON suivant :

\/Date(1293034567877)\/

qui est le résultat de ce code .NET :

var obj = DateTime.Now;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializer.Serialize(obj).Dump();

Le problème auquel je suis confronté est de savoir comment créer un objet Date à partir de cet objet en JavaScript. Tout ce que j'ai pu trouver, c'est une incroyable solution de type regex (qui contient de nombreux bugs).

Il est difficile de croire qu'il n'y a pas de solution élégante car tout cela est en JavaScrip, je veux dire un code JavaScript qui essaie de lire JSON (JavaScript Object Notation) qui est censé être un code JavaScript et à ce moment-là, il s'avère que ce n'est pas le cas parce que JavaScript ne peut pas faire du bon travail ici.

J'ai également vu des solutions d'évaluation que je n'ai pas pu faire fonctionner (en plus d'être signalées comme une menace pour la sécurité).

N'y a-t-il vraiment aucun moyen de le faire de manière élégante ?

Question similaire sans véritable réponse :
Comment analyser le format de date ASP.NET JSON avec GWT

2 votes

Vous pouvez simplement transmettre l'horodatage au client et appeler new Date() sur celui-ci.

0 votes

Si j'avais un horodatage, je pourrais, mais j'ai JSON que JavaScript ne comprend apparemment pas [sic !].

141voto

Tim Points 321

En JSON.parse accepte une fonction optionnelle d'inversion de la date et de l'heure. Vous pouvez utiliser une fonction comme celle-ci :

dateTimeReviver = function (key, value) {
    var a;
    if (typeof value === 'string') {
        a = /\/Date\((\d*)\)\//.exec(value);
        if (a) {
            return new Date(+a[1]);
        }
    }
    return value;
}

Appelez ensuite

JSON.parse(somejsonstring, dateTimeReviver);

Et vos dates seront respectées.

6 votes

Cette pratique consistant à encoder des données de type non primitif dans un type primitif (chaîne de caractères) est insensée. Encodez les dates dans un objet JSON avec des propriétés significatives, ou pour aller encore plus loin, incluez une propriété "$type" dans l'objet JSON afin que la routine de parse/désérialisation puisse faire revivre le type de manière appropriée et même utiliser des convertisseurs personnalisés si vous voulez rassembler toutes les informations dans une seule valeur de propriété comme "ticks" ou "ms_since_epoch".

7 votes

J'ai dû modifier l'expression rationnelle comme suit : /\Date((- ? \d *))\// pour qu'il puisse également traiter les nombres négatifs. Les nombres négatifs apparaissent lorsque vous avez une très vieille DateTime (avant l'époque) qui a été convertie par .NET en JSON.

0 votes

@ClearCloud8 : Il manque des barres obliques inverses : /\Date\((- ? \d *)\)\//

56voto

Jacob Points 33729

Il n'existe pas de représentation JSON standard des dates. Vous devriez faire ce que @jAndy a suggéré et ne pas sérialiser un fichier DateTime Il suffit d'envoyer une chaîne de date RFC 1123 ToString("r") ou un nombre de secondes à partir de l'époque d'Unix, ou quelque chose d'autre que vous pouvez utiliser dans le JavaScript pour construire un Date .

3 votes

Merci, je m'engageais dans une voie sans issue, vous avez été le premier à signaler que JSON ne supporte pas le type Date.

3 votes

JSON prend en charge les nombres, les chaînes de caractères, les objets, les tableaux et les valeurs littérales true, false et null. La date n'étant rien de tout cela, il s'agit d'un type complexe qui doit être stocké en tant qu'objet, plutôt qu'en tant que chaîne de caractères. Vous pouvez donc inclure des informations de type telles que le nom du type dans des membres spéciaux tels que "$type" qui ne se résoudraient jamais en un membre objet réel. De tels méta-membres peuvent être utilisés pour faire revivre l'objet JSON en tant qu'objet d'exécution à typage fort plus tard. Je pense que la pratique consistant à coller une date dans une chaîne est stupide, car elle crée inutilement des motifs de chaîne réservés et tente de les faire correspondre à chaque chaîne.

4 votes

Il existe désormais un format de date JSON standard. tools.ietf.org/html/rfc7493#section-4.3

51voto

treeface Points 7972

Cette réponse de Roy Tinker ici :

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

Comme il le dit lui-même : La fonction substr supprime la partie "/Date(", et la fonction parseInt obtient l'entier et ignore le ")/" à la fin. Le nombre résultant est passé dans le constructeur de la date.

Une autre option consiste à formater correctement vos informations du côté ASP de manière à ce que JavaScript puisse les lire facilement. Envisagez de le faire pour vos dates :

DateTime.Now()

qui devrait renvoyer un format comme celui-ci :

7/22/2008 12:11:04 PM

Si vous passez ceci dans un fichier JavaScript Date comme ceci :

var date = new Date('7/22/2008 12:11:04 PM');

La variable date détient désormais cette valeur :

Tue Jul 22 2008 12:11:04 GMT-0700 (Pacific Daylight Time)

Naturellement, vous pouvez formater ceci DateTime en n'importe quel type de chaîne/int que le JS Date accepte.

0 votes

Merci treeface, cette réponse m'a aidé à résoudre un problème récent !

4 votes

Ne jamais, au grand jamais, se fier aux formats de conversion date<->chaîne par défaut. L'utilisation des millisecondes depuis l'époque, qui reste dans le domaine des types numériques, est bien plus simple et plus fiable.

2 votes

Cette réponse présente deux solutions - la première est correcte (le parseInt) et la seconde fausse, donc je ne sais pas s'il faut mettre un upvote ou un downvote ! Le problème avec une sortie sous forme de chaîne de caractères est que la date peut facilement être inversée si le serveur se trouve dans un pays, par exemple les États-Unis, et le navigateur dans un autre, par exemple le Royaume-Uni.

11voto

ViPuL5 Points 89

Vous pouvez convertir une date JSON au format normal en JavaScript.

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

6voto

Psytronic Points 2886

Qu'est-ce qui ne va pas avec :

new Date(1293034567877);

Cela donne pour moi "Wed Dec 22 2010 16:16:07 GMT+0000 (GMT Standard Time)".

Ou bien avez-vous besoin d'extraire le numéro du json ?

3 votes

Qu'est-ce qui ne va pas dans votre solution ? Le 1293034567877 n'est pas le JSON que j'ai, n'est-ce pas ? De plus, je n'ai pas besoin d'extraire le nombre du JSON, j'ai besoin d'extraire la date du JSON. J'attends un peu plus de JavaScript que d'être capable de tout faire avec des expressions rationnelles. J'ai besoin que mon code soit lisible et qu'il ne ressemble pas à une malédiction de dessin animé.

7 votes

Je reprocherais à .NET de produire une sérialisation d'un objet date dans un format aussi bizarre que \/Date(1293034567877)\/ . S'il était sain d'esprit, il produirait simplement l'heure d'origine et vous pourriez initialiser un objet Date avec cela.

0 votes

J'ai procédé comme le propose Psytronic. Le problème est qu'il ne s'agit pas d'une date JSON, mais d'une date .NET. Ce n'est pas un grand problème d'analyser un nombre à partir de la chaîne, n'est-ce pas ?

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