[jquery] Wie formatiere ich ein Microsoft JSON-Datum?



Answers

Sie können dies verwenden, um ein Datum von JSON zu erhalten:

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

Und dann können Sie ein JavaScript-Datumsformat- Skript (1,2 KB, wenn minimiert und gezippt) verwenden, um es wie gewünscht anzuzeigen.

Question

Ich mache meinen ersten Crack bei Ajax mit jQuery. Ich erhalte meine Daten auf meiner Seite, aber ich habe Probleme mit den JSON-Daten, die für die Datentypen "Datum" zurückgegeben werden. Im Grunde genommen bekomme ich eine Schnur zurück, die so aussieht:

/Date(1224043200000)/

Von jemandem, der JSON völlig neu ist - Wie formatiere ich das in ein kurzes Datumsformat? Sollte dies irgendwo im jQuery-Code behandelt werden? Ich habe versucht, das jQuery.UI.datepicker Plugin mit $.datepicker.formatDate() ohne Erfolg.

FYI: Hier ist die Lösung, die ich mit einer Kombination der Antworten hier gefunden habe:

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

Diese Lösung hat mein Objekt von der Callback-Methode erhalten und die Daten auf der Seite korrekt mit der Date-Format-Bibliothek angezeigt.




In tollem Thread schreiben:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));



Das ursprüngliche Beispiel:

/Date(1224043200000)/  

spiegelt nicht die von WCF verwendete Formatierung wider, wenn Daten über WCF-REST mithilfe der integrierten JSON-Serialisierung gesendet werden. (zumindest auf .NET 3.5, SP1)

Ich fand die Antwort hier hilfreich, aber eine geringfügige Bearbeitung der Regex ist erforderlich, da es scheint, dass der Zeitzonen-GMT-Offset an die Zahl angehängt wird, die seit 1970 in WCF JSON zurückgegeben wird.

In einem WCF-Dienst habe ich:

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

ApptVisitLinkInfo ist einfach definiert:

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

Wenn "Field2" als Json vom Dienst zurückgegeben wird, lautet der Wert:

/Date(1224043200000-0600)/

Beachten Sie, dass der Zeitzonenoffset als Teil des Werts enthalten ist.

Die modifizierte Regex:

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

Es ist etwas eifriger und packt alles zwischen den Parens, nicht nur die erste Nummer. Die daraus resultierende Zeit sinze 1970 plus Zeitzonen-Offset können alle in das Eval eingegeben werden, um ein Datumsobjekt zu erhalten.

Die resultierende JavaScript-Zeile für das Ersetzen lautet:

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



Das ist frustrierend. Meine Lösung bestand darin, das "/ und /" aus dem von ASP.NETs JavaScriptSerializer generierten Wert zu analysieren, so dass JSON zwar kein Datumsliteral hat, aber vom Browser immer noch als Datum interpretiert wird, was ich wirklich alles ist will: {"myDate":Date(123456789)}

Benutzerdefinierter JavaScriptConverter für DateTime?

Ich muss die Genauigkeit von Roy Tinkers Kommentar hervorheben. Dies ist kein legales JSON. Es ist ein schmutziger, schmutziger Hack auf dem Server, um das Problem zu beheben, bevor es zu einem Problem für JavaScript wird. Es wird einen JSON-Parser ersticken. Ich habe es benutzt, um vom Boden aufzustehen, aber ich benutze es nicht mehr. Allerdings glaube ich immer noch, dass die beste Antwort darin liegt, zu ändern, wie der Server das Datum formatiert, zum Beispiel ISO, wie an anderer Stelle erwähnt.




Dies kann Ihnen auch helfen.

 function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
        var pattern = /Date\(([^)]+)\)/;
        var results = pattern.exec(value);
        var dt = new Date(parseFloat(results[1]));
        return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
    }



Unten ist eine ziemlich einfache Lösung zum Analysieren von JSON-Daten. Verwenden Sie die folgenden Funktionen gemäß Ihrer Anforderung. Sie müssen nur das als Parameter abgerufene JSON-Format Date an die folgenden Funktionen übergeben:

function JSONDate(dateStr) {
    var m, day;
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    return (m + '/' + day + '/' + d.getFullYear())
}

function JSONDateWithTime(dateStr) {
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    var m, day;
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    var formattedDate = m + "/" + day + "/" + d.getFullYear();
    var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
    var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
    var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
    formattedDate = formattedDate + " " + formattedTime;
    return formattedDate;
}



Mootools Lösung:

new Date(Date(result.AppendDts)).format('%x')

Benötigt mootools-more. Getestet mit mootools-1.2.3.1-more auf Firefox 3.6.3 und IE 7.0.5730.13




Um nur einen weiteren Ansatz hier hinzuzufügen, ist der "Ticks-Ansatz", den WCF annimmt, anfällig für Probleme mit Zeitzonen, wenn Sie nicht extrem vorsichtig sind, wie here und an anderen Stellen beschrieben. Daher verwende ich jetzt das ISO 8601-Format, das sowohl .NET als auch JavaScript ordnungsgemäß unterstützt, einschließlich Zeitzonen-Offsets. Unten sind die Details:

In WCF / .NET:

Wo CreationDate eine System.DateTime ist; ToString ("o") verwendet den Round-trip-Formatbezeichner von .NET, der eine ISO 8601-kompatible Datumszeichenfolge generiert

new MyInfo {
    CreationDate = r.CreationDate.ToString("o"),
};

In JavaScript

Kurz nach dem Abrufen des JSONs gehe ich die Daten zu JavaSript Date-Objekten mit dem Date-Konstruktor, der eine ISO 8601-Datumszeichenkette akzeptiert ...

$.getJSON(
    "MyRestService.svc/myinfo",
    function (data) {
        $.each(data.myinfos, function (r) {
            this.CreatedOn = new Date(this.CreationDate);
        });
        // Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
       alert(data.myinfos[0].CreationDate.toLocaleString());
    }
)

Sobald Sie ein JavaScript-Datum haben, können Sie alle praktischen und zuverlässigen Date-Methoden wie toDateString , toLocaleString usw. verwenden.




Wenn Sie in JavaScript sagen,

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

Sie werden sehen, dass es das richtige Datum ist, und Sie können das überall in JavaScript-Code mit jedem Framework verwenden.




Aktualisiert

Wir haben eine interne UI-Bibliothek, die sowohl mit dem integrierten ASP.NET-JSON-Format von Microsoft, wie /Date(msecs)/ , das hier ursprünglich abgefragt wurde, als auch mit dem 2014-06-22T00:00:00.0 Format, einschließlich 2014-06-22T00:00:00.0 . Außerdem müssen wir mit der Unfähigkeit von altIE fertig werden, mit nur 3 Nachkommastellen fertig zu werden .

Wir erkennen zuerst, welche Art von Datum wir verbrauchen, parsen es in ein normales JavaScript- Date Objekt und formatieren es dann.

1) Erkenne Microsoft Datumsformat

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

2) Erkenne das ISO-Datumsformat

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 Datumsformat:

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

4) Parse ISO Datumsformat.

Wir können zumindest sichergehen, dass es sich um Standard-ISO-Daten oder ISO-Daten handelt, die so geändert wurden, dass sie immer drei Millisekunden haben ( siehe oben ). Daher ist der Code abhängig von der Umgebung unterschiedlich.

4a) Parse Standard-ISO-Datumsformat, bewältigen Sie die Probleme von 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 mit einer festen drei Millisekunden Dezimalstellen - viel einfacher:

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

5) Formatiere es:

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) Binde alles zusammen:

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

    return formatDate(d);
}

Die folgende alte Antwort ist nützlich, um diese Datumsformatierung in jQuerys JSON-Parsing zu binden, so dass Sie Date-Objekte anstelle von Strings erhalten oder wenn Sie immer noch in jQuery <1.5 stecken bleiben.

Alte Antwort

Wenn Sie die Ajax-Funktion von jQuery 1.4 mit ASP.NET MVC verwenden, können Sie alle DateTime-Eigenschaften in Date-Objekte umwandeln mit:

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

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

In jQuery 1.5 können Sie vermeiden, dass die parseJSON Methode global überschrieben wird, indem Sie die Option converters im Ajax-Aufruf verwenden.

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

Leider müssen Sie zu der älteren Eval-Route wechseln, um Daten zu erhalten, die global in-place analysiert werden. Andernfalls müssen Sie sie im Einzelfall nach der Analyse konvertieren.




Überprüfen Sie den Datum ISO-Standard; so ähnlich:

yyyy.MM.ddThh:mm

Es wird 2008.11.20T22:18 .




json2.js Sie in jQuery 1.5 json2.js für ältere Browser verwenden, können Sie alle von Ajax kommenden Daten wie folgt deserialisieren:

(function () {
    var DATE_START = "/Date(";
    var DATE_START_LENGTH = DATE_START.length;

    function isDateString(x) {
        return typeof x === "string" && x.startsWith(DATE_START);
    }

    function deserializeDateString(dateString) {
        var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
        var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
        return utcDate;
    }

    function convertJSONDates(key, value) {
      if (isDateString(value)) {
        return deserializeDateString(value);
      }
      return value;
    }

    window.jQuery.ajaxSetup({
      converters: {
        "text json": function(data) {
          return window.JSON.parse(data, convertJSONDates);
        }
      }
    });
}());

Ich habe Logik eingefügt, die davon ausgeht, dass Sie alle Daten vom Server als UTC senden (was Sie sollten); Der Konsument erhält dann ein JavaScript- Date Objekt, das den richtigen Tick-Wert aufweist, um dies widerzuspiegeln. Das heißt, getUTCHours() usw. am Datum getUTCHours() wird, wird der gleiche Wert wie auf dem Server zurückgegeben, und getHours() ruft den Wert in der lokalen Zeitzone des Benutzers zurück, wie vom Browser festgelegt.

Dies berücksichtigt WCF Format mit Zeitzonenversätzen nicht, obwohl das relativ einfach hinzuzufügen wäre.




FYI, für jeden, der Python auf der Serverseite benutzt: datetime.datetime (). Ctime () gibt eine Zeichenkette zurück, die nativ von "new Date ()" geparst werden kann. Das heißt, wenn Sie eine neue datetime.datetime-Instanz erstellen (z. B. mit datetime.datetime.now), kann die Zeichenfolge in die JSON-Zeichenfolge eingeschlossen werden, und diese Zeichenfolge kann dann als erstes Argument an den Date-Konstruktor übergeben werden. Ich habe noch keine Ausnahmen gefunden, aber ich habe es auch nicht zu streng getestet.




Die Benutzung des Datepickers der jQuery-Benutzeroberfläche ist nur dann sinnvoll, wenn Sie bereits die jQuery-Benutzeroberfläche enthalten:

$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6)))); 

Ausgabe:

15. Oktober 2008




Am Ende fügte ich die "Zeichen" in den regulären Ausdruck von Panos ein, um die vom Microsoft Serializer erzeugten zu entfernen, wenn Objekte in ein Inline-Skript geschrieben wurden:

Also, wenn Sie eine Eigenschaft in Ihrem C # code-behind , ist das etwas wie

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

Und in deiner Aspx hast du

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

Du würdest sowas bekommen

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

Beachten Sie die Anführungszeichen.

Um dies in eine Form zu bringen, die eval korrekt deserialisiert, benutzte ich:

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

Ich benutze Prototype und verwende es, fügte ich hinzu

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





Links