Domanda Come si formatta una data Microsoft JSON?


Sto prendendo il mio primo crack a Ajax con jQuery. Inserisco i miei dati nella mia pagina, ma sto riscontrando dei problemi con i dati JSON restituiti per i tipi di dati Date. Fondamentalmente, sto ottenendo una stringa che assomiglia a questo:

/Date(1224043200000)/

Da qualcuno totalmente nuovo a JSON - Come faccio a formattarlo in un formato a data breve? Questo dovrebbe essere gestito da qualche parte nel codice jQuery? Ho provato il jQuery.UI.datepicker plugin usando $.datepicker.formatDate() senza alcun successo.

A proposito: ecco la soluzione che ho trovato usando una combinazione delle risposte qui:

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;
}

Questa soluzione ha ottenuto il mio oggetto dal metodo di callback e ha mostrato correttamente le date sulla pagina utilizzando la libreria del formato della data.


1787


origine


risposte:


Eval non è necessario. Questo funzionerà bene:

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

La funzione substr prende la parte "/ Date (", e la funzione parseInt ottiene il numero intero e ignora ") /" alla fine. Il numero risultante viene passato al costruttore Date.

EDIT: ho intenzionalmente omesso la radice (il secondo argomento di parseInt); vedere il mio commento qui sotto. Inoltre, sono completamente d'accordo Il commento di Rory: Le date ISO-8601 sono preferite rispetto a questo vecchio formato, quindi questo formato generalmente non dovrebbe essere usato per nuovi sviluppi. Vedi l'eccellente Json.NET libreria per un'ottima alternativa che serializza le date utilizzando il formato ISO-8601.

Per le date JSON formattate ISO-8601, basta passare la stringa nel costruttore Date:

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

1565



Puoi usarlo per ottenere una data da JSON:

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

E poi puoi usare un formato data JavaScript script (1,2 KB quando minified e gzip) per visualizzarlo come vuoi.


115



Per chi usa Newtonsoft Json.NET, leggi su come farlo via JSON nativo in IE8, Firefox 3.5 e Json.NET.

Anche la documentazione sulla modifica del formato delle date scritte da Json.NET è utile: Serializzare le date con Json.NET

Per quelli che sono troppo pigri, ecco i passi veloci. Poiché JSON ha un'implementazione DateTime libera, è necessario utilizzare il IsoDateTimeConverter(). Si noti che dal momento che Json.NET 4.5 il formato data predefinito è ISO, quindi il codice sottostante non è necessario.

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

Il JSON passerà come

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

Infine, alcuni JavaScript per convertire la data ISO in una data 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;
}

L'ho usato così

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

84



L'esempio originale:

/Date(1224043200000)/  

non riflette la formattazione utilizzata da WCF quando si inviano le date tramite WCF REST utilizzando la serializzazione JSON incorporata. (almeno su .NET 3.5, SP1)

Ho trovato la risposta utile, ma è necessaria una leggera modifica alla regex, poiché sembra che l'offset GMT del fuso orario sia stato aggiunto al numero restituito (dal 1970) in WCF JSON.

In un servizio WCF ho:

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

ApptVisitLinkInfo è definito semplicemente:

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

Quando "Field2" viene restituito come Json dal servizio, il valore è:

/Date(1224043200000-0600)/

Si noti l'offset del fuso orario incluso come parte del valore.

La regex modificata:

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

È leggermente più impaziente e afferra tutto tra i paren, non solo il primo numero. Il tempo risultante 1970, oltre allo sfasamento del fuso orario, possono essere tutti inseriti nell'eval per ottenere un oggetto data.

La riga risultante di JavaScript per la sostituzione è:

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

57



Non ripeterti: automatizza la conversione della data utilizzando $.parseJSON()

Le risposte al tuo post forniscono la conversione manuale della data in date JavaScript. Ho esteso jQuery $.parseJSON() solo un po ', quindi è in grado di analizzare automaticamente le date quando lo istruisci. Elabora le date formattate ASP.NET (/Date(12348721342)/) così come le date formattate ISO (2010-01-01T12.34.56.789Z) supportati dalle funzioni JSON native nei browser (e librerie come json2.js).

Comunque. Se non desideri ripetere più volte il codice di conversione della data, ti suggerisco di leggere questo post del blog e prendi il codice che ti renderà la vita un po 'più facile.


53



Se dici in JavaScript,

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

vedrai che è la data corretta e puoi utilizzarla ovunque nel codice JavaScript con qualsiasi framework.


50



Clicca qui per verificare la demo

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();

Risultato - "15/10/2008"


46



aggiornato

Abbiamo una libreria UI interna che deve far fronte sia al formato JSON incorporato di Microsoft ASP.NET, come /Date(msecs)/, ha chiesto informazioni su qui in origine, e la maggior parte del formato di data di JSON incluso JSON.NET, come 2014-06-22T00:00:00.0. Inoltre, dobbiamo farcela L'incapacità di oldie di far fronte a qualsiasi cosa tranne 3 posizioni decimali.

Per prima cosa rileviamo quale tipo di data stiamo consumando, analizzandolo in un normale JavaScript Date oggetto, quindi formattarlo.

1) Rileva il formato della data di Microsoft

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

2) Rileva il formato della data 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) Formato della data MS Parse:

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

4) Formato della data ISO Parse.

Almeno abbiamo un modo per essere sicuri che abbiamo a che fare con date ISO standard o date ISO modificate per avere sempre tre millisecondi (vedi sopra), quindi il codice è diverso a seconda dell'ambiente.

4a) Formato standard per la data ISO standard, per far fronte ai problemi di 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) Formato Parse ISO con cifre decimali fisse di tre millisecondi: molto più semplice:

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

5) Formattalo:

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) Lega tutto insieme:

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

    return formatDate(d);
}

La precedente risposta è utile per legare questa formattazione della data al parsing JSON di jQuery in modo da ottenere oggetti Date invece di stringhe o se in qualche modo sei ancora bloccato in jQuery <1.5.

Vecchia risposta

Se stai utilizzando la funzione Ajax di jQuery 1.4 con ASP.NET MVC, puoi trasformare tutte le proprietà DateTime in oggetti Date con:

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

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

In jQuery 1.5 puoi evitare di sovrascrivere il parseJSON metodo a livello globale utilizzando l'opzione convertitori nella chiamata Ajax.

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

Sfortunatamente devi passare alla vecchia eval route per far sì che le date vengano analizzate globalmente sul posto, altrimenti è necessario convertirle in base al caso dopo l'analisi caso per caso.


31



Ho anche dovuto cercare una soluzione a questo problema e alla fine mi sono imbattuto in moment.js che è una bella libreria in grado di analizzare questo formato data e molti altri.

var d = moment(yourdatestring)

Mi ha salvato un po 'di mal di testa quindi ho pensato di condividerlo con te. :)
Puoi trovare qualche informazione in più qui: http://momentjs.com/


21



Ho finito per aggiungere i "caratteri nell'espressione regolare di Panos per sbarazzarsi di quelli generati dal serializzatore Microsoft per quando si scrivono oggetti in uno script inline:

Quindi se hai una proprietà nel tuo C # code-behind è qualcosa di simile

protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}

E nel tuo aspx hai

<script type="text/javascript">
    var myObject = '<%= JsonObject %>';
</script>

Otterresti qualcosa di simile

var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';

Notare le doppie virgolette.

Per ottenere questo in una forma che la valutazione ha correttamente deserializzato, ho usato:

myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');

Io uso Prototipo e per usarlo ho aggiunto

String.prototype.evalJSONWithDates = function() {
    var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
    return jsonWithDates.evalJSON(true);
}

21