Wie formatiere ich ein Microsoft JSON-Datum?


2000

Ich mache meinen ersten Crack bei Ajax mit jQuery. Ich erhalte meine Daten auf meine Seite, habe jedoch Probleme mit den JSON-Daten, die für Datumsdatentypen zurückgegeben werden. Grundsätzlich bekomme ich eine Zeichenfolge zurück, die so aussieht:

/Date(1224043200000)/

Von jemandem, der für JSON völlig neu ist - Wie formatiere ich dies auf ein kurzes Datumsformat? Sollte dies irgendwo im jQuery-Code behandelt werden? Ich habe das jQuery.UI.datepickerPlugin $.datepicker.formatDate()ohne Erfolg ausprobiert .

Zu Ihrer Information: 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 Rückrufmethode abgerufen und die Daten auf der Seite mithilfe der Datumsformatbibliothek korrekt angezeigt.


26
Dies könnte interessant sein: hanselman.com/blog/…
citronas

6
Das Format /Date(...)/ ist spezifisch für das in Microsoft integrierte JSON-Datumsformat - es ist nicht Teil eines Standards, und JSON, das aus Javascript stammt, hat einen Standard: Das ISO-Format Javascript gibt Folgendes an: stackoverflow.com/a / 15952652/176877 Diese Frage ist also spezifisch für das JSON-Datumsformat von Microsoft. Ich habe den Titel geändert, um dies zu verdeutlichen.
Chris Moschini

15
Du machst Witze! Microsoft hat JSON seinen eigenen Dreh gegeben! und an Terminen !! Wann werden sie lernen!
Nick.McDermaid

Verwenden Sie Newtonsoft JSON auf der .NET-Seite und verwenden Sie einfach: github.com/RickStrahl/json.date-extensions
baHI

Sie können JSON ++ anstelle von JSON verwenden. JSON ++ ist dasselbe wie JSON, unterstützt jedoch JavaScript-Typen wie Date.
Brillout

Antworten:


1688

eval()ist nicht nötig. Dies wird gut funktionieren:

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

Die substr()Funktion nimmt den /Date(Teil heraus und die parseInt()Funktion erhält die Ganzzahl und ignoriert die )/am Ende. Die resultierende Nummer wird an den DateKonstruktor übergeben.


Ich habe den Radix absichtlich weggelassen (das 2. Argument dazu parseInt); siehe meinen Kommentar unten .

Außerdem stimme ich Rorys Kommentar voll und ganz zu : ISO-8601-Daten werden diesem alten Format vorgezogen - daher sollte dieses Format im Allgemeinen nicht für Neuentwicklungen verwendet werden. In der hervorragenden Json.NET- Bibliothek finden Sie eine großartige Alternative zum Serialisieren von Datumsangaben im ISO-8601-Format.

Übergeben Sie für ISO-8601-formatierte JSON-Daten einfach die Zeichenfolge an den DateKonstruktor:

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

4
@Broam: Beide Methoden (die Ersetzungsfunktion und diese Antwort) müssten sich ändern, wenn MS das Format ändert.
Roy Tinker

23
Könnten Sie es bitte mit dem radix var date = new Date aktualisieren (parseInt (jsonDate.substr (6), 10));
James Kyburz

6
@ JamesKyburz: Jede Regel hat Ausnahmen, und ich denke, dies ist, wenn eine Ausnahme gilt. Die JSON-Datumsnummern von .NET haben niemals eine führende "0", sodass wir den Radix sicher weglassen können.
Roy Tinker

22
Es ist erwähnenswert, dass dieses Datumsformat ziemlich schlecht ist und die allgemeine Umstellung auf ISO-8601-formatierte Datumsangaben in JSON erfolgt. Siehe hanselman.com/blog/…
Rory

4
Bei diesem Ansatz wird die Zeitzone nicht berücksichtigt, sodass schwerwiegende Probleme auftreten können, wenn sich Server und Benutzer in unterschiedlichen Zeitzonen befinden. Ich habe unten eine Antwort gepostet, die eine sehr schnelle und einfache Möglichkeit erklärt, auf WCF-
Scott Willeke

135

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

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

Anschließend können Sie ein JavaScript- Skript für das Datumsformat (1,2 KB beim Minimieren und Komprimieren) verwenden, um es nach Ihren Wünschen anzuzeigen.


7
Es ist nichts falsch mit der Zeile, die Reihenfolge ist \ //. Der erste Schrägstrich wird maskiert, sodass er nicht wie ein Kommentar zählt. Es ist Ihr Editor, der Sie austrickst, die Zeile wird gut funktionieren.
andreialecu

152
@ Ball, Unsinn:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
Augenlidlosigkeit

39
pst war richtig, es ist möglich, dies auf verschiedene Arten ohne 'eval' zu tun. Crockford sagt, dass 'eval Is Evil', weil es weniger lesbar und weniger sicher ist, außerdem impliziert er möglicherweise, dass es weniger effizient und gefährlicher ist, weil es den Javascript-Compiler trifft.
Mark Rogers

13
@Edy: new Functionist fast so schlimm wie eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel

5
@Edy: Das ist eine andere Form der Bewertung und ist genauso 'böse'. Analysieren Sie stattdessen die Zeichenfolge (siehe meine Antwort unten)
Roy Tinker

98

Informationen zur Verwendung von Newtonsoft Json.NET finden Sie unter Native JSON in IE8, Firefox 3.5 und Json.NET .

Auch die Dokumentation zum Ändern des Datumsformats von Json.NET ist hilfreich: Serialisieren von Daten mit Json.NET

Für diejenigen, die zu faul sind, hier sind die schnellen Schritte. Da JSON eine lose DateTime-Implementierung hat, müssen Sie die verwenden IsoDateTimeConverter(). Beachten Sie, dass seit Json.NET 4.5 das Standard-Datumsformat ISO ist, sodass der folgende Code nicht benötigt wird.

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

Der JSON wird als durchkommen

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

Zum Schluss noch etwas JavaScript, um das ISO-Datum in ein JavaScript-Datum umzuwandeln:

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

Ich habe es so benutzt

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

6
Der JavaScript-Datumskonstruktor kann die Zeichenfolge für Sie analysieren:new Date("2009-04-12T20:44:55")
David Hogue

5
Warnung - Die Date () - Konstruktorformate und das Parsen sind vor ECMAScript 6 nicht Standard. Beispielsweise behandelt IE 9 das Datum, das Sie dem Konstruktor geben, als Ortszeit, selbst wenn es sich in IS0-8601 befindet, was überall als UCT impliziert wird. Verlassen Sie sich nicht auf den Datumskonstruktor, wenn Sie ältere Browser unterstützen. codeofmatt.com/2013/06/07/…
DanO

Das Senden eines Nicht-UTC-Datums bringt Sie früher oder später in Schwierigkeiten.
Tymtam

Ein bisschen zu spät zur Party hier, aber was würde (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ;; in diesem Zusammenhang darstellen?
Yanant

@yanant - das +a[1]etc repräsentiert die Array-Teile des regulären Ausdrucks und das +würde es auf eine Zahl umwandeln , also +a[1]gleich 2009usw. Hier ist die Array-Aufschlüsselung: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong

67

Das ursprüngliche Beispiel:

/Date(1224043200000)/  

spiegelt nicht die Formatierung wider, die WCF beim Senden von Daten über WCF REST mithilfe der integrierten JSON-Serialisierung verwendet. (zumindest unter .NET 3.5, SP1)

Ich fand die Antwort hier hilfreich, aber eine geringfügige Änderung des regulären Ausdrucks ist erforderlich, da anscheinend der GMT-Versatz der Zeitzone an die in WCF JSON zurückgegebene Nummer (seit 1970) angehängt wird.

In einem WCF-Dienst habe ich:

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

ApptVisitLinkInfo wird einfach definiert:

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

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

/Date(1224043200000-0600)/

Beachten Sie den Zeitzonenversatz, der als Teil des Werts enthalten ist.

Der modifizierte reguläre Ausdruck:

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

Es ist etwas eifriger und packt alles zwischen den Eltern, nicht nur die erste Nummer. Die resultierende Zeitsinze 1970 plus Zeitzonenversatz kann alle in die Auswertung eingespeist werden, um ein Datumsobjekt zu erhalten.

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

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

10
Dies ist falsch. Das neue Datum (1224043200000-0600) subtrahiert nur 600 vom Datum, in diesem Fall 600 Millisekunden, nicht 6 Stunden, wie es sollte.
Ariel

@ariel: Werfen Sie einen Blick auf Javascript Datum aus Millisekunden und Zeitzone
Bergi

Ich denke, der Zeitzonenversatz ist nur enthalten, wenn Sie eine Zeitzone für das DateTime-Objekt in .NET haben (dies ist das Standardverhalten). Wenn Ihr Datum in UTC ist, verwenden Sie DateTime.SpecifyKind (Datum, DateTimeKind.UTC) und Sie erhalten den richtigen UTC-Wert, wenn es ohne Offset serialisiert wird, den Sie dann nach Bedarf in die Zeitzone des Benutzers zurückkonvertieren können. Wenn es in der Ortszeit ist, verwenden Sie .ToUniversalTime () und es wird in UTC konvertiert und die "Art" ist bereits für Sie angegeben.
Jvenema

in Javascript -0100 wird eine binäre Zeichenfolge sein, seien Sie also vorsichtig!
Verbedr

Wenn Sie das Datum von WCF in JS konvertiert haben, wie wäre es mit umgekehrt. Sie müssen ein Datum als Ganzzahl (mit date.getTime ()) angeben, das Sie an dieselbe WCF übergeben möchten?
NitinSingh

65

Wiederholen Sie sich nicht - automatisieren Sie die Datumskonvertierung mit $.parseJSON()

Antworten auf Ihren Beitrag bieten eine manuelle Datumskonvertierung in JavaScript-Datumsangaben. Ich habe jQuery's $.parseJSON()nur ein wenig erweitert, damit es Daten automatisch analysieren kann, wenn Sie es anweisen. Es verarbeitet ASP.NET-formatierte Datumsangaben ( /Date(12348721342)/) sowie ISO-formatierte Datumsangaben ( 2010-01-01T12.34.56.789Z), die von nativen JSON-Funktionen in Browsern (und Bibliotheken wie json2.js) unterstützt werden.

Wie auch immer. Wenn Sie Ihren Datumskonvertierungscode nicht immer wieder wiederholen möchten, empfehlen wir Ihnen, diesen Blog-Beitrag zu lesen und den Code zu erhalten, der Ihnen das Leben ein wenig erleichtert.


61

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 im JavaScript-Code mit jedem Framework verwenden.


3
Das hätte ich auch gedacht, außer es wäre: var thedate = / Date (1224043200000) /; Zumindest für mich ...
Rball

2
Datum () und Datum (1224043200000) liefern sowohl in Chrome als auch in Firefox das gleiche Ergebnis. Ich bin mir nicht sicher, ob dies in alten Browsern funktioniert hat, aber diese Antwort funktioniert jetzt nicht in Browsern.
James

@ James, Ja, es gibt das aktuelle Datum des Browsers an. :(
vissu

9
Sie müssen es als "neues Datum (1224043200000)" schreiben.
BrainSlugs83

60

Klicken Sie hier, um die Demo zu überprüfen

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

Ergebnis - "15.10.2008"


Nur eine Verbesserung für die obige Methode. Funktion formatearFecha (fec) {var value = neues Datum (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, ''))); var mes = value.getMonth (); var dia = value.getDate (); var date = dia + "/" + mes + "/" + value.getFullYear (); if (dia <10) date = date.substr (0, 0) + '0' + dia + date.substr (1); if (mes <10) date = date.substr (0, 3) + '0' + mes + date.substr (4); return date;} date formatiert auf ddMMyyyy. Prost!
Matias

38

Aktualisiert

Wir haben eine interne UI-Bibliothek, die sowohl mit dem in Microsoft /Date(msecs)/ursprünglich nach ASP.NET integrierten JSON-Format, wie hier ursprünglich gefragt, als auch mit dem Datumsformat der meisten JSONs, einschließlich JSON.NET, wie z 2014-06-22T00:00:00.0. Außerdem müssen wir mit der Unfähigkeit von oldIE fertig werden, mit etwas anderem als 3 Dezimalstellen fertig zu werden .

Wir erkennen zuerst, welche Art von Datum wir verbrauchen, analysieren es in ein normales JavaScript- DateObjekt und formatieren es dann aus.

1) Ermitteln Sie das Microsoft-Datumsformat

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

2) Ermitteln Sie 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) Analysieren Sie das MS-Datumsformat:

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

4) Analysieren Sie das ISO-Datumsformat.

Wir können zumindest sicherstellen, dass es sich um Standard-ISO-Daten oder ISO-Daten handelt, die so geändert wurden, dass sie immer drei Millisekunden-Stellen haben ( siehe oben ), sodass der Code je nach Umgebung unterschiedlich ist.

4a) Analysieren Sie das Standard-ISO-Datumsformat und 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) Analysieren Sie das ISO-Format mit einer festen Dezimalstelle von drei Millisekunden - viel einfacher:

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

5) Formatieren Sie 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 die JSON-Analyse von jQuery einzubinden, damit Sie Datumsobjekte anstelle von Zeichenfolgen erhalten oder wenn Sie immer noch in jQuery <1.5 stecken.

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 das parseJSONglobale Überschreiben der Methode vermeiden, indem Sie die Konverteroption im Ajax-Aufruf verwenden.

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

Leider müssen Sie zur älteren Bewertungsroute wechseln, damit Dates global an Ort und Stelle analysiert werden können. Andernfalls müssen Sie sie nach der Analyse von Fall zu Fall konvertieren.


27

In JSON ist kein Datumstyp integriert . Dies sieht aus wie die Anzahl der Sekunden / Millisekunden aus einer Epoche. Wenn Sie die Epoche kennen, können Sie das Datum erstellen, indem Sie die richtige Zeit hinzufügen.


Das ist falsch. JSON verwendet Javascript-Daten mit zusätzlichen Zeitzoneninformationen. Die Epoche entspricht der Epoche der Javascript-Datumsklasse (aus offensichtlichen Gründen).
BrainSlugs83

3
@ BrainSlug83 - Diese Antwort enthält eine Referenz für die Behauptung, dass JSON keinen integrierten Datumstyp hat. Wenn Sie nicht einverstanden sind, geben Sie bitte eine alternative Referenz an. (Sie denken nicht an ein bestimmtes Framework, das sich für ein Zeichenfolgenformat zur Darstellung von Datumsangaben entschieden hat, oder? Dies ist nicht Teil des JSON-Standards, kann jedoch nicht daran liegen, dass es unmöglich wäre, eine Zeichenfolge einzuschließen, die dies nicht ist soll als Datum genommen werden, aber das hat zufällig eine Reihe von Zeichen, die dem
Datumsmuster entsprechen

25

Ich musste auch nach einer Lösung für dieses Problem suchen und stieß schließlich auf moment.js, eine nette Bibliothek, die dieses Datumsformat und vieles mehr analysieren kann.

var d = moment(yourdatestring)

Es ersparte mir Kopfschmerzen und ich dachte, ich würde es mit Ihnen teilen. :)
Weitere Informationen dazu finden Sie hier: http://momentjs.com/


24

Am Ende habe ich die "Zeichen in den regulären Ausdruck von Panos eingefügt, um die vom Microsoft-Serialisierer generierten Zeichen zu entfernen, wenn Objekte in ein Inline-Skript geschrieben werden:

Wenn Sie also eine Eigenschaft in Ihrem C # -Code-Behind haben , ist das so etwas wie

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

Und in deinem Aspx hast du

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

Du würdest so etwas bekommen

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

Beachten Sie die doppelten Anführungszeichen.

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

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

Ich benutze Prototype und um es zu benutzen, habe ich hinzugefügt

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

22

In jQuery 1.5 können Sie alle von Ajax stammenden Daten wie folgt deserialisieren , solange Sie json2.js für ältere Browser verwenden müssen:

(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 eine Logik eingefügt, die davon ausgeht, dass Sie alle Daten vom Server als UTC senden (was Sie sollten). Der Verbraucher erhält dann ein JavaScript- DateObjekt, das den richtigen Ticks-Wert hat, um dies widerzuspiegeln. Das heißt, Anrufe getUTCHours()usw. am Datum geben den gleichen Wert zurück wie auf dem Server und rufen angetHours() den Wert in der lokalen Zeitzone des Benutzers zurück, der von seinem Browser festgelegt wurde.

Das WCF- Format mit Zeitzonen-Offsets wird dabei nicht berücksichtigt , obwohl dies relativ einfach hinzuzufügen wäre.


Nur als Hinweis: Damit der Code funktioniert, müssen Sie die StartsWith-Methode vom Typ String erstellen
Hugo Zapata

21

Verwenden des Datumsauswahlprogramms für die jQuery-Benutzeroberfläche - ist nur dann wirklich sinnvoll, wenn Sie die jQuery-Benutzeroberfläche bereits einbeziehen:

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

Ausgabe:

15. Oktober 2008


20

Überdenken Sie das nicht. Übergeben Sie, wie wir es seit Jahrzehnten tun, einen numerischen Versatz von der De-facto-Standardepoche vom 1. Januar 1970 um Mitternacht GMT / UTC / & c in Sekunden (oder Millisekunden) seit dieser Epoche. JavaScript mag es, Java mag es, C mag es und das Internet mag es.


2
Und schade, es stehen mehr als 20 Epochen zur Auswahl. en.wikipedia.org/wiki/Epoch_(reference_date)
Jerther


18

Jede dieser Antworten hat eines gemeinsam: Sie alle speichern Datumsangaben als einen einzigen Wert (normalerweise als Zeichenfolge).

Eine andere Möglichkeit besteht darin, die inhärente Struktur von JSON zu nutzen und ein Datum als Liste von Zahlen darzustellen:

{ "name":"Nick",
  "birthdate":[1968,6,9] }

Natürlich müssten Sie sicherstellen, dass beide Enden der Konversation über das Format (Jahr, Monat, Tag) und die Felder als Datumsangaben übereinstimmen. Dies hat jedoch den Vorteil, dass die Datumsangabe vollständig vermieden wird -zu-String-Konvertierung. Es sind alles Zahlen - überhaupt keine Zeichenketten. Die Verwendung der Reihenfolge: Jahr, Monat, Tag ermöglicht auch eine ordnungsgemäße Sortierung nach Datum.

Denken Sie hier nur über den Tellerrand hinaus - ein JSON-Datum muss nicht als Zeichenfolge gespeichert werden.

Ein weiterer Vorteil dieser Methode besteht darin, dass Sie einfach (und effizient) alle Datensätze für ein bestimmtes Jahr oder einen bestimmten Monat auswählen können, indem Sie die Art und Weise nutzen, wie CouchDB Abfragen zu Array-Werten verarbeitet.


In JSON gibt es ein Standardformat für Datumsangaben, nämlich das RFC 3339-Format.
Gnasher729

@gnasher, das wäre schön, ist aber nicht der Fall. Es gibt keine Referenzen von RFC 7159 bis 3339 oder umgekehrt. Es gibt kein de jure Standard-JSON-Datumsformat. Alles, was übrig bleibt, sind De-facto- Standards, von denen jeder Vor- / Nachteile hat. Das ist das Schöne an Standards.
Marc L.

17

Posting in einem tollen Thread:

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

1
Gute Idee, aber was ist, wenn ein Zeitzonenversatz enthalten ist? Verwenden Sie in diesem Fall lieber substr (6) anstelle von Slice (6, -2) - siehe meine Antwort unten.
Roy Tinker

17

Um hier noch einen weiteren Ansatz hinzuzufügen: Der von WCF verfolgte "Ticks-Ansatz" ist anfällig für Probleme mit Zeitzonen, wenn Sie nicht besonders vorsichtig sind, wie hier und an anderen Stellen beschrieben. Daher verwende ich jetzt das ISO 8601-Format, das sowohl von .NET als auch von JavaScript ordnungsgemäß unterstützt wird und Zeitzonen-Offsets enthält. Unten sind die Details:

In WCF / .NET:

Wobei CreationDate ein System.DateTime ist; ToString ( „o“) wird unter Verwendung von .NET Round-Trip - Formatbezeichner , die ein ISO 8601-konforme Datums - Zeichenfolge erzeugt

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

In JavaScript

Unmittelbar nach dem Abrufen des JSON korrigiere ich die Daten als JavaSript Date-Objekte mit dem Date-Konstruktor, der eine ISO 8601-Datumszeichenfolge 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 Datumsmethoden wie toDateString , toLocaleString usw. verwenden.


16
var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

Gibt es eine andere Option ohne Verwendung der jQuery-Bibliothek?


Dies ist eine neue Frage und sollte als eigene Frage gestellt und hier nicht eingebettet werden.
Spencer Sullivan

11

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

10

Im Folgenden finden Sie eine ziemlich einfache Lösung zum Parsen von JSON-Daten. Verwenden Sie die folgenden Funktionen gemäß Ihren Anforderungen. Sie müssen nur das als Parameter abgerufene Datum im JSON-Format 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;
}

10

Sie können auch die JavaScript-Bibliothek moment.js verwenden , die nützlich ist, wenn Sie planen, mit verschiedenen lokalisierten Formaten umzugehen und andere Vorgänge mit Datumswerten auszuführen:

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

    function (result) {
        $("#AuthMerchId").text(result.AuthorizationMerchantId);
        $("#SttlMerchId").text(result.SettlementMerchantId);
        $("#CreateDate").text(moment(result.AppendDts).format("L"));
        $("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
        $("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
        $("#LastUpdatedBy").text(result.LastUpdateNt);
        $("#ProcessIn").text(result.ProcessIn);
    }
    );
    return false;
}

Das Einrichten der Lokalisierung ist so einfach wie das Hinzufügen von Konfigurationsdateien (Sie erhalten sie bei momentjs.com) zu Ihrem Projekt und das Konfigurieren der Sprache:

moment.lang('de');

9

Ich bekomme das Datum so:

"/Date(1276290000000+0300)/"

In einigen Beispielen liegt das Datum in leicht unterschiedlichen Formaten vor:

"/Date(12762900000000300)/"
"Date(1276290000000-0300)"

usw.

Also habe ich mir folgendes RegExp ausgedacht:

/\/+Date\(([\d+]+)\)\/+/

und der endgültige Code lautet:

var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));

Ich hoffe es hilft.

Update: Ich habe diesen Link von Microsoft gefunden: Wie serialisiere ich Daten mit JSON?

Dies scheint die zu sein, nach der wir alle suchen.


1
Regexp-Ersetzungen sind langsam ... Es ist viel schneller, den ganzzahligen Teil mit substr (6) zu erfassen und an parseInt () zu übergeben - siehe meine Antwort unten.
Roy Tinker


9

Überprüfen Sie das Datum ISO-Standard; irgendwie so:

yyyy.MM.ddThh:mm

Es wird 2008.11.20T22:18.


Gemäß JSON-Schema entspricht das Format "Datum / Uhrzeit" RFC 3339, Abschnitt 5.6. Sie sollten also "yyyy-MM-ddTHH: mm: ssZ" für Daten in GMT schreiben oder das Z durch eine Zeitzone wie + hh: mm ersetzen.
Gnasher729

Das Problem ist, dass WCF und andere "alte" MS JSON-Serialisierungen dieses Format nicht verwenden und dies berücksichtigt werden muss.
Marc L.

9

Das ist frustrierend. Meine Lösung bestand darin, das "/ und /" aus dem vom JavaScriptSerializer von ASP.NET generierten Wert zu analysieren, damit JSON zwar kein Datumsliteral hat, es jedoch vom Browser als Datum interpretiert wird, was alles ist, was ich wirklich bin wollen:{"myDate":Date(123456789)}

Benutzerdefinierter JavaScriptConverter für DateTime?

Ich muss die Richtigkeit von Roy Tinkers Kommentar betonen. Dies ist kein legaler 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 abzuheben, aber ich benutze es nicht mehr. Ich bin jedoch der Meinung, dass die beste Antwort darin besteht, die Formatierung des Datums durch den Server zu ändern, z. B. ISO, wie an anderer Stelle erwähnt.


2
Das ist kein legaler JSON. Dies funktioniert nur bei der Bewertung mit einem Javascript-Interpreter. Wenn Sie jedoch einen JSON-Decoder verwenden, wird dieser ersticken.
Roy Tinker

1
Einverstanden. Und wenn ich mich nur mit diesem einen Datenelement befassen würde, würde ich es nicht in Betracht ziehen. Wenn es sich jedoch um ein Objekt mit mehreren Daten und anderen Eigenschaften handelt, ist es einfacher, das Ganze zu bewerten (), als die Eigenschaften einzeln auszuwählen. Am Ende ist das Hauptproblem das Fehlen eines (legalen) JSON-Datums. Bis dies existiert, bleiben wir unseren kreativen Hacks überlassen.
StarTrekRedneck

8

Ein später Beitrag, aber für diejenigen, die diesen Beitrag durchsucht haben.

Stell dir das vor:

    [Authorize(Roles = "Administrator")]
    [Authorize(Roles = "Director")]
    [Authorize(Roles = "Human Resources")]
    [HttpGet]
    public ActionResult GetUserData(string UserIdGuidKey)
    {
        if (UserIdGuidKey!= null)
        {
            var guidUserId = new Guid(UserIdGuidKey);
            var memuser = Membership.GetUser(guidUserId);
            var profileuser = Profile.GetUserProfile(memuser.UserName);
            var list = new {
                              UserName = memuser.UserName,
                              Email = memuser.Email ,
                              IsApproved = memuser.IsApproved.ToString() ,
                              IsLockedOut = memuser.IsLockedOut.ToString() ,
                              LastLockoutDate = memuser.LastLockoutDate.ToString() ,
                              CreationDate = memuser.CreationDate.ToString() ,
                              LastLoginDate = memuser.LastLoginDate.ToString() ,
                              LastActivityDate = memuser.LastActivityDate.ToString() ,
                              LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
                              IsOnline = memuser.IsOnline.ToString() ,
                              FirstName = profileuser.FirstName ,
                              LastName = profileuser.LastName ,
                              NickName = profileuser.NickName ,
                              BirthDate = profileuser.BirthDate.ToString() ,
            };
            return Json(list, JsonRequestBehavior.AllowGet);
        }
        return Redirect("Index");
    }

Wie Sie sehen können, verwende ich die Funktion von C # 3.0 zum Erstellen der "Auto" -Generika. Es ist ein bisschen faul, aber ich mag es und es funktioniert. Nur eine Anmerkung: Profil ist eine benutzerdefinierte Klasse, die ich für mein Webanwendungsprojekt erstellt habe.


Jedes Mal, wenn Sie eine neue Rolle hinzufügen [Authorize (Roles = "Human Resources")], müssen Sie kompilieren und bereitstellen? wow .... :)
Alex Nolasco

1
Wenn dies ein JSON-Dienst ist, scheint die Umleitung falsch zu sein. Ich würde einen 404 Not Found zurückgeben, wenn der Eingabeschlüssel so ungültig ist, dass er möglicherweise nicht gefunden werden kann (und auch einen 404, wenn er wirklich nicht gefunden wird). Wenn meine Benutzer nicht angemeldet sind, gebe ich 403 Forbidden zurück.
Richard Corfield

Es ist eine "wiederverwendbare" Methode. Wenn ich beispielsweise Benutzerdaten aus einer anderen Ansicht abrufen möchte, kann ich sie abrufen, solange ich die ID gebe. Wenn die ID jedoch nicht angegeben wird, wird die Seite zu einer Benutzerliste (Index) umgeleitet, um einen Benutzer auszuwählen. Einfache Lösung für die App, genau so, wie mein Gehirn es damals gemacht hat.
Ray Linder

8

Zu Ihrer Information, für alle, die Python auf der Serverseite verwenden: datetime.datetime (). Ctime () gibt eine Zeichenfolge zurück, die nativ nach "new Date ()" analysiert werden kann. Wenn Sie also eine neue datetime.datetime-Instanz erstellen (z. B. mit datetime.datetime.now), kann die Zeichenfolge in die JSON-Zeichenfolge aufgenommen 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.


8

Mootools-Lösung:

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

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


8
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];

8

Fügen Sie das jQuery UI- Plugin zu Ihrer Seite hinzu:

function DateFormate(dateConvert) {
    return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};

8

Was ist, wenn .NET zurückkehrt ...

return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"

Und dann in JavaScript ...

var x = new Date("2013-09-17 15:18:53Z");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.