Question Comment formater une date Microsoft JSON?


Je prends ma première fissure à Ajax avec jQuery. J'obtiens mes données sur ma page, mais j'ai des problèmes avec les données JSON retournées pour les types de données Date. Fondamentalement, je reçois une chaîne qui ressemble à ceci:

/Date(1224043200000)/

De quelqu'un de totalement nouveau à JSON - Comment puis-je formater ceci à un format de date courte? Cela devrait-il être traité quelque part dans le code jQuery? J'ai essayé le jQuery.UI.datepicker plugin en utilisant $.datepicker.formatDate() sans succès.

FYI: Voici la solution que j'ai trouvée en utilisant une combinaison de réponses ici:

function getMismatch(id) {
  $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
      $("#AuthMerchId").text(result.AuthorizationMerchantId);
      $("#SttlMerchId").text(result.SettlementMerchantId);
      $("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
      $("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
      $("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
      $("#LastUpdatedBy").text(result.LastUpdateNt);
      $("#ProcessIn").text(result.ProcessIn);
    }
  );

  return false;
}

function formatJSONDate(jsonDate) {
  var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
  return newDate;
}

Cette solution a obtenu mon objet de la méthode de rappel et affiché correctement les dates sur la page en utilisant la bibliothèque de format de date.


1788


origine


Réponses:


L'évaluation n'est pas nécessaire. Cela fonctionnera bien:

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

La fonction substr supprime la partie "/ Date (", et la fonction parseInt récupère l'entier et ignore ") /" à la fin. Le nombre résultant est passé dans le constructeur Date.

EDIT: J'ai volontairement omis la base (le 2ème argument de parseInt); voir mon commentaire ci-dessous. En outre, je suis entièrement d'accord avec Le commentaire de Rory: Les dates ISO-8601 sont préférées à cet ancien format. Par conséquent, ce format ne doit généralement pas être utilisé pour un nouveau développement. Voir l'excellent Json.NET bibliothèque pour une excellente alternative qui sérialise les dates en utilisant le format ISO-8601.

Pour les dates JSON au format ISO-8601, il suffit de passer la chaîne dans le constructeur Date:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support

1565



Vous pouvez l'utiliser pour obtenir une date à partir de JSON:

var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));

Et puis vous pouvez utiliser un format de date JavaScript script (1,2 Ko lorsque minifié et gzippé) pour l'afficher comme vous le souhaitez.


115



Pour ceux qui utilisent Newtonsoft Json.NET, lisez sur comment le faire via JSON natif dans IE8, Firefox 3.5 et Json.NET.

Aussi la documentation sur la modification du format des dates écrites par Json.NET est utile: Sérialisation des dates avec Json.NET

Pour ceux qui sont trop paresseux, voici les étapes rapides. Comme JSON a une implémentation libre de DateTime, vous devez utiliser le IsoDateTimeConverter(). Notez que depuis Json.NET 4.5 le format de date par défaut est ISO donc le code ci-dessous n'est pas nécessaire.

string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());

Le JSON viendra à travers comme

"fieldName": "2009-04-12T20:44:55"

Enfin, du JavaScript pour convertir la date ISO en une date JavaScript:

function isoDateReviver(value) {
  if (typeof value === 'string') {
    var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
      if (a) {
        var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
        return new Date(utcMilliseconds);
      }
  }
  return value;
}

Je l'ai utilisé comme ça

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);

84



L'exemple original:

/Date(1224043200000)/  

ne reflète pas la mise en forme utilisée par WCF lors de l'envoi de dates via WCF REST à l'aide de la sérialisation JSON intégrée. (au moins sur .NET 3.5, SP1)

J'ai trouvé la réponse utile, mais une légère modification de la regex est nécessaire, car il semble que le décalage GMT du fuseau horaire soit ajouté au numéro renvoyé (depuis 1970) dans WCF JSON.

Dans un service WCF, j'ai:

[OperationContract]
[WebInvoke(
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.WrappedRequest
    )]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );

ApptVisitLinkInfo est défini simplement:

public class ApptVisitLinkInfo {
    string Field1 { get; set; }
    DateTime Field2 { get; set; }
    ...
}

Lorsque "Field2" est renvoyé en tant que Json à partir du service, la valeur est:

/Date(1224043200000-0600)/

Notez le décalage de fuseau horaire inclus dans le cadre de la valeur.

L'expression rationnelle modifiée:

/\/Date\((.*?)\)\//gi

Il est légèrement plus désireux et attrape tout entre les parens, pas seulement le premier nombre. L'heure résultante sinze 1970, plus décalage de fuseau horaire peuvent tous être introduits dans l'eval pour obtenir un objet de date.

La ligne de JavaScript résultante pour le remplacement est:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");

57



Ne vous répétez pas - automatisez la conversion de date en utilisant $.parseJSON()

Les réponses à votre publication fournissent une conversion manuelle des dates en JavaScript. J'ai étendu jQuery $.parseJSON() juste un peu, donc il est capable d'analyser automatiquement les dates quand vous le lui demandez. Il traite les dates au format ASP.NET (/Date(12348721342)/) ainsi que les dates formatées ISO (2010-01-01T12.34.56.789Z) qui sont pris en charge par les fonctions JSON natives dans les navigateurs (et les bibliothèques comme json2.js).

En tous cas. Si vous ne voulez pas répéter votre code de conversion de date encore et encore, je vous suggère de lire ce blog et obtenez le code qui vous facilitera la vie.


53



Si vous dites en JavaScript,

var thedate = new Date(1224043200000);
alert(thedate);

vous verrez que c'est la date correcte, et vous pouvez l'utiliser n'importe où dans le code JavaScript avec n'importe quel framework.


50



Cliquez ici pour vérifier la démo

JavaScript / jQuery

var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
            (
                 parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
            );
var dat = value.getMonth() +
                         1 +
                       "/" +
           value.getDate() +
                       "/" +
       value.getFullYear();

Résultat - "10/15/2008"


46



Actualisé

Nous avons une bibliothèque d'interface utilisateur interne qui doit gérer à la fois le format JSON intégré ASP.NET de Microsoft, comme /Date(msecs)/, interrogé ici à l'origine, et la plupart des formats de date de JSON, y compris JSON.NET, comme 2014-06-22T00:00:00.0. En outre, nous devons faire face à L'incapacité d'oldIE à faire face à tout sauf 3 décimales.

Nous détectons d'abord le type de date que nous consommons, analysons-le dans un JavaScript normal Date objet, puis formater cela.

1) Détecter le format de date Microsoft

// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
    return /^\/Date\(/.test(s);
}

2) Détecter le format de date ISO

var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;

function looksLikeIsoDate(s) {
    return isoDateRegex.test(s);
}

3) Parse MS format de date:

function parseMSDate(s) {
    // Jump forward past the /Date(, parseInt handles the rest
    return new Date(parseInt(s.substr(6)));
}

4) Analyser le format de date ISO.

Nous avons au moins un moyen de nous assurer que nous traitons des dates ISO standard ou des dates ISO modifiées pour toujours avoir trois millisecondes (voir au dessus), donc le code est différent en fonction de l'environnement.

4a) Analyser le format de date ISO standard, faire face aux problèmes de oldIE:

function parseIsoDate(s) {
    var m = isoDateRegex.exec(s);

    // Is this UTC, offset, or undefined? Treat undefined as UTC.
    if (m.length == 7 ||                // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
        (m.length > 7 && (
            !m[7] ||                    // Array came back length 9 with undefined for 7 and 8
            m[7].charAt(0) != '.' ||    // ms portion, no tz offset, or no ms portion, Z
            !m[8] ||                    // ms portion, no tz offset
            m[8] == 'Z'))) {            // ms portion and Z
        // JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
        var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
    } else {
        // local
        var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
    }

    return d;
}

4b) Parse ISO format avec une décimale fixe de trois millisecondes - beaucoup plus facile:

function parseIsoDate(s) {
    return new Date(s);
}

5) Formatez-le:

function hasTime(d) {
    return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}

function zeroFill(n) {
    if ((n + '').length == 1)
        return '0' + n;

    return n;
}

function formatDate(d) {
    if (hasTime(d)) {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
        s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
    } else {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
    }

    return s;
}

6) Attachez tout ensemble:

function parseDate(s) {
    var d;
    if (looksLikeMSDate(s))
        d = parseMSDate(s);
    else if (looksLikeIsoDate(s))
        d = parseIsoDate(s);
    else
        return null;

    return formatDate(d);
}

L'ancienne réponse ci-dessous est utile pour lier cette mise en forme de date à l'analyse JSON de jQuery afin d'obtenir des objets Date au lieu de chaînes, ou si vous êtes toujours bloqué dans jQuery <1.5.

Vieille réponse

Si vous utilisez la fonction Ajax de jQuery 1.4 avec ASP.NET MVC, vous pouvez convertir toutes les propriétés DateTime en objets Date avec:

// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};

$.ajax({
    ...
    dataFilter: function(d) {
        return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
    },
    ...
});

Dans jQuery 1.5, vous pouvez éviter de surcharger parseJSON méthode globalement en utilisant l'option convertisseurs dans l'appel Ajax.

http://api.jquery.com/jQuery.ajax/

Malheureusement, vous devez passer à l'ancienne route d'évaluation afin d'obtenir des dates à analyser globalement sur place - sinon vous devez les convertir plus au cas par cas après l'analyse.


31



J'ai également dû chercher une solution à ce problème et finalement je suis tombé sur le moment.js qui est une belle bibliothèque qui peut analyser ce format de date et beaucoup plus.

var d = moment(yourdatestring)

Cela m'a sauvé un peu de mal de tête alors j'ai pensé que je le partagerais avec vous. :)
Vous pouvez trouver plus d'informations à ce sujet ici: http://momentjs.com/


21