Jak sformatować datę Microsoft JSON?


1999

Pierwszy raz robię crack w Ajaxie z jQuery. Dostaję moje dane na moją stronę, ale mam problemy z danymi JSON zwracanymi dla typów danych Date. Zasadniczo otrzymuję ciąg znaków, który wygląda następująco:

/Date(1224043200000)/

Od kogoś zupełnie nowego do JSON - Jak sformatować to na krótki termin? Czy należy to rozwiązać gdzieś w kodzie jQuery? Próbowałem jQuery.UI.datepickerużywać wtyczki $.datepicker.formatDate()bez powodzenia.

FYI: Oto rozwiązanie, które wymyśliłem, używając kombinacji odpowiedzi tutaj:

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

To rozwiązanie pobrało mój obiekt z metody wywołania zwrotnego i poprawnie wyświetlało daty na stronie przy użyciu biblioteki formatu daty.


26
To może być interesujące: hanselman.com/blog/…
citronas

6
Format /Date(...)/ jest specyficzny dla wbudowanego formatu Microsoft JSON Date - nie jest częścią żadnego standardu, a JSON, pochodzący z Javascript, ma standard: Format ISO JavaScript określa: stackoverflow.com/a / 15952652/176877 To pytanie dotyczy formatu daty JSON firmy Microsoft. Zmodyfikowałem tytuł, aby to wyjaśnić.
Chris Moschini

15
Żartujesz! Microsoft stworzył własny spin na JSON! i na randki !! Kiedy się nauczą!
Nick.McDermaid

Użyj Newtonsoft JSON po stronie .NET, a aby mieć ładne wartości wpisane po stronie JS, po prostu użyj: github.com/RickStrahl/json.date-extensions
baHI

Możesz użyć JSON ++ zamiast JSON. JSON ++ jest taki sam jak JSON, ale obsługuje typy JavaScript takie jak Date.
brillout

Odpowiedzi:


1688

eval()to nie jest konieczne. To zadziała dobrze:

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

substr()Funkcja wyjmuje /Date(część oraz parseInt()funkcja pobiera całkowitą i ignoruje )/na końcu. Wynikowa liczba jest przekazywana do Datekonstruktora.


Celowo pominąłem podstawkę (drugi argument do parseInt); zobacz mój komentarz poniżej .

Ponadto całkowicie zgadzam się z komentarzem Rory'ego : daty ISO-8601 są preferowane w stosunku do tego starego formatu - więc ten format zasadniczo nie powinien być używany do nowego programowania. Zobacz doskonałą bibliotekę Json.NET, która stanowi doskonałą alternatywę szeregowania dat przy użyciu formatu ISO-8601.

W przypadku dat JSON sformatowanych według ISO-8601 wystarczy przekazać ciąg do Datekonstruktora:

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

4
@Broam: Obie metody (funkcja zamiany i ta odpowiedź) musiałyby ulec zmianie, gdyby MS zmieniło format.
Roy Tinker,

23
Czy mógłbyś zaktualizować go o radix var date = new Date (parseInt (jsonDate.substr (6), 10));
James Kyburz,

6
@JamesKyburz: Każda reguła ma wyjątki i myślę, że wtedy ma zastosowanie wyjątek. Numery dat JSON z .NET nigdy nie mają wiodącego „0”, więc możemy bezpiecznie pominąć podstawkę.
Roy Tinker,

22
Warto zauważyć, że ten format daty jest dość zły, a ogólny ruch to daty sformatowane w ISO-8601 w JSON. Zobacz hanselman.com/blog/…
Rory

4
To podejście nie uwzględnia strefy czasowej, więc może powodować poważne problemy, gdy serwer i użytkownicy znajdują się w różnych strefach czasowych. Poniżej zamieściłem odpowiedź, która wyjaśnia bardzo szybki i łatwy sposób radzenia sobie z tym po stronie WCF i Javascript: stackoverflow.com/a/10743718/51061
Scott Willeke

135

Możesz użyć tego, aby uzyskać datę z JSON:

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

Następnie możesz użyć skryptu formatu daty JavaScript (1,2 KB po zminimalizowaniu i spakowaniu gzip), aby wyświetlić go tak, jak chcesz.


7
Z linią nie ma nic złego, sekwencja to \ //. Pierwszy ukośnik jest usuwany, więc nie liczy się jak komentarz. Edytor cię oszuka, linia będzie działać dobrze.
andreialecu

152
@rball, nonsens:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
powiek

39
pst miał rację, można to zrobić na wiele sposobów bez „eval”. Crockford mówi, że „eval Is Evil”, ponieważ jest mniej czytelny i mniej bezpieczny, może ponadto sugerować, że jest mniej wydajny i bardziej niebezpieczny, ponieważ uderza w kompilator javascript.
Mark Rogers,

13
@Edy: new Functionjest prawie tak zły, jak eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel,

5
@Edy: To kolejna forma ewaluacji i jest równie „zła”. Zamiast tego przeanalizuj ciąg znaków (patrz moja odpowiedź poniżej)
Roy Tinker

98

Dla tych, którzy używają Newtonsoft Json.NET , przeczytaj, jak to zrobić przez Native JSON w IE8, Firefox 3.5 oraz Json.NET .

Przydatna jest również dokumentacja dotycząca zmiany formatu dat napisana przez Json.NET: Serializacja dat w Json.NET

Dla tych, którzy są zbyt leniwi, oto krótkie kroki. Ponieważ JSON ma luźną implementację DateTime, musisz użyć IsoDateTimeConverter(). Zauważ, że od Json.NET 4.5 domyślnym formatem daty jest ISO, więc poniższy kod nie jest potrzebny.

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

JSON przejdzie jako

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

Na koniec niektóre JavaScript do konwersji daty ISO na datę 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;
}

Użyłem tego w ten sposób

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

6
Konstruktor daty JavaScript może przetworzyć dla Ciebie ciąg znaków:new Date("2009-04-12T20:44:55")
David Hogue,

5
Ostrzeżenie - formaty konstruktora Date () i parsowanie są niestandardowe przed ECMAScript 6. Na przykład IE 9 traktuje datę podaną przez konstruktora jako czas lokalny, nawet jeśli jest to IS0-8601, co jest domniemane jako UCT wszędzie indziej. Nie obsługuj konstruktora daty, jeśli obsługujesz starsze przeglądarki. codeofmatt.com/2013/06/07/…
DanO

Wysyłanie daty spoza UTC prędzej czy później wpędzi Cię w kłopoty.
tymtam,

Trochę późno na imprezę tutaj, ale co by (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; reprezentować w tym kontekście?
yanant

@yanant - +a[1]etc reprezentuje elementy tablicy wyrażenia regularnego, a +rzutowałby ją na liczbę, więc +a[1]jest równa 2009itp. Oto podział tablicy: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong

67

Oryginalny przykład:

/Date(1224043200000)/  

nie odzwierciedla formatowania używanego przez WCF podczas wysyłania dat przez REST WCF przy użyciu wbudowanej serializacji JSON. (przynajmniej w .NET 3.5, SP1)

Uznałem, że odpowiedź tutaj jest pomocna, ale wymagana jest niewielka modyfikacja wyrażenia regularnego, ponieważ wydaje się, że przesunięcie strefy czasowej GMT jest dołączane do liczby zwracanej (od 1970 r.) W WCF JSON.

W serwisie WCF mam:

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

ApptVisitLinkInfo definiuje się po prostu:

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

Gdy „Field2” jest zwracane jako Json z usługi, wartość wynosi:

/Date(1224043200000-0600)/

Zwróć uwagę na przesunięcie strefy czasowej uwzględnione jako część wartości.

Zmodyfikowane wyrażenie regularne:

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

Jest nieco bardziej chętny i chwyta wszystko między parens, nie tylko pierwszą liczbę. Wynikowy czas sinze 1970 plus przesunięcie strefy czasowej można wprowadzić do eval, aby uzyskać obiekt daty.

Wynikowa linia JavaScript do zamiany to:

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

10
to źle, nowa data (1224043200000-0600) odejmie tylko 600 od daty, w tym przypadku 600 milisekund, a nie 6 godzin, jak powinno.
ariel


Myślę, że przesunięcie strefy czasowej jest uwzględnione tylko wtedy, gdy masz strefę czasową obiektu DateTime w .NET (co jest zachowaniem domyślnym). Jeśli twoja data jest w UTC, użyj DateTime.SpecifyKind (date, DateTimeKind.UTC), a otrzymasz szeregową wartość UTC, gdy zostanie ona serializowana, bez przesunięcia, które możesz później w razie potrzeby przekonwertować z powrotem do strefy czasowej użytkownika. Jeśli jest to czas lokalny, użyj .ToUniversalTime (), a zostanie przekonwertowany na UTC i będzie miał dla ciebie już określony „Rodzaj”.
jvenema

w javascript -0100 będzie ciągiem binarnym, więc bądź ostrożny!
verbedr

po przekonwertowaniu daty z WCF na JS, co powiesz na odwrócenie. Musisz podać datę jako liczbę całkowitą (używając date.getTime ()), którą chcesz przekazać do tego samego WCF?
NitinSingh

65

Nie powtarzaj się - zautomatyzuj konwersję dat za pomocą $.parseJSON()

Odpowiedzi na Twój post zapewniają ręczną konwersję dat na daty JavaScript. Rozszerzyłem jQuery $.parseJSON()tylko trochę, więc jest w stanie automatycznie parsować daty, kiedy go poinstruujesz. Przetwarza daty w formacie ASP.NET ( /Date(12348721342)/) oraz daty w formacie ISO ( 2010-01-01T12.34.56.789Z), które są obsługiwane przez rodzime funkcje JSON w przeglądarkach (i bibliotekach takich jak json2.js).

Tak czy siak. Jeśli nie chcesz powtarzać kodu konwersji daty w kółko, sugeruję przeczytanie tego postu na blogu i uzyskanie kodu, który ułatwi ci życie.


61

Jeśli powiesz w JavaScript,

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

zobaczysz, że jest to poprawna data i możesz jej użyć w dowolnym miejscu w kodzie JavaScript z dowolnym frameworkiem.


3
Tak też bym pomyślał, gdyby nie koniec: var thedate = / Date (1224043200000) /; przynajmniej dla mnie ...
rball

2
Zarówno Date (), jak i Date (1224043200000) dają ten sam wynik zarówno w Chrome, jak i Firefox. Nie jestem pewien, czy to działało w starych przeglądarkach, ale ta odpowiedź nie działa teraz w przeglądarkach.
James

@James, Tak, podaje aktualną datę przeglądarki. :(
vissu,

9
Musisz zapisać go jako „nową datę (1224043200000)”.
BrainSlugs83

60

Kliknij tutaj, aby sprawdzić wersję 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();

Wynik - „10/15/2008”


Tylko ulepszenie powyższej metody. funkcja formatearFecha (fec) {var value = new Date (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, ''))); var mes = value.getMonth (); var dia = wartość.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); data powrotu;} data sformatowana na ddMMyyyy, zdrowie!
Matias

38

Zaktualizowano

Mamy wewnętrzną bibliotekę interfejsu użytkownika, która musi poradzić sobie zarówno z wbudowanym formatem JSON Microsoft.NET.NET firmy Microsoft, jak /Date(msecs)/pierwotnie zapytano o nią, jak i z większością formatu daty JSON, w tym JSON.NET 2014-06-22T00:00:00.0. Ponadto musimy poradzić sobie z niezdolnością oldIE do radzenia sobie z czymkolwiek innym niż 3 miejsca dziesiętne .

Najpierw wykrywamy, jaką datę zużywamy, analizujemy w zwykły Dateobiekt JavaScript , a następnie formatujemy.

1) Wykryj format daty Microsoft

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

2) Wykryj format daty 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) Format daty parsowania MS:

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

4) Analizuj format daty ISO.

Mamy przynajmniej sposób na upewnienie się, że mamy do czynienia ze standardowymi datami ISO lub datami ISO zmodyfikowanymi tak, aby zawsze miały trzy milisekundowe miejsca ( patrz wyżej ), więc kod różni się w zależności od środowiska.

4a) Analizować standardowy format daty ISO, radzić sobie z problemami 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) Parsuj format ISO ze stałymi miejscami dziesiętnymi milisekund - znacznie łatwiej:

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

5) Sformatuj:

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) Zwiąż wszystko razem:

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

    return formatDate(d);
}

Poniższa stara odpowiedź jest przydatna do powiązania formatowania daty z własnym parsowaniem JSON jQuery, aby uzyskać obiekty Date zamiast ciągów, lub jeśli nadal utkniesz w jQuery <1.5.

Stara odpowiedź

Jeśli używasz funkcji Ajax jQuery 1.4 z ASP.NET MVC, możesz przekształcić wszystkie właściwości DateTime w obiekty Date za pomocą:

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

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

W jQuery 1.5 możesz uniknąć parseJSONglobalnego zastąpienia metody, używając opcji konwerterów w wywołaniu Ajax.

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

Niestety musisz przełączyć się na starszą ścieżkę ewaluacyjną, aby Daty mogły parsować globalnie w miejscu - w przeciwnym razie musisz je przekonwertować po analizie poszczególnych przypadków.


27

W JSON nie ma wbudowanego typu daty . Wygląda to na liczbę sekund / milisekund z pewnej epoki. Jeśli znasz epokę, możesz utworzyć datę, dodając odpowiednią ilość czasu.


To niepoprawne, JSON używa dat Javascript z dodanymi informacjami o strefie czasowej - epoka jest taka sama jak epoka klasy Date javascript (z oczywistych powodów).
BrainSlugs83

3
@ BrainSlug83 - ta odpowiedź zawiera odniesienie do twierdzenia, że ​​JSON nie ma wbudowanego typu daty. Jeśli się nie zgadzasz, podaj alternatywne odniesienie. (Nie myślisz o konkretnym frameworku, który zdecydował się na format ciągu do reprezentowania dat, prawda? powinna być traktowana jako data, ale zdarza się, że zawiera zestaw znaków pasujących do wzorca daty).
nnnnnn

25

Musiałem także znaleźć rozwiązanie tego problemu i ostatecznie natknąłem się na moment.js, która jest fajną biblioteką, która może analizować ten format daty i wiele innych.

var d = moment(yourdatestring)

Oszczędzało mi to bólu głowy, więc pomyślałem, że podzielę się tym z tobą. :)
Więcej informacji na ten temat można znaleźć tutaj: http://momentjs.com/


24

Skończyło się na dodawaniu „znaków do wyrażenia regularnego Panos, aby pozbyć się tych generowanych przez serializator Microsoft podczas pisania obiektów w skrypcie wbudowanym:

Więc jeśli masz właściwość w swoim C # za kodem , to coś takiego

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

A w aspx masz

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

Dostałbyś coś takiego

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

Zwróć uwagę na podwójne cytaty.

Aby przekształcić to w postać, która eval poprawnie poprawi deserializację, użyłem:

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

Używam Prototypu i do tego dodałem

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

22

W jQuery 1.5, o ile masz plik json2.js na starsze przeglądarki, możesz dokonać deserializacji wszystkich dat pochodzących z Ajax w następujący sposób:

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

Podałem logikę, która zakłada, że ​​wysyłasz wszystkie daty z serwera jako UTC (co powinieneś); konsument otrzymuje następnie Dateobiekt JavaScript, który ma odpowiednią wartość tików, aby to odzwierciedlić. Oznacza to, że wywołanie getUTCHours()itp. W dniu zwróci tę samą wartość, co na serwerze, a wywołanie getHours()zwróci wartość w lokalnej strefie czasowej użytkownika określonej przez przeglądarkę.

Nie bierze to pod uwagę formatu WCF z przesunięciami stref czasowych, chociaż byłoby to stosunkowo łatwe do dodania.


Uwaga: aby kod działał, musisz utworzyć metodę beginWith typu łańcucha
Hugo Zapata,

21

Korzystanie z datepicker interfejsu użytkownika jQuery - naprawdę ma sens tylko wtedy, gdy już dołączasz interfejs użytkownika jQuery:

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

wynik:

15 października 2008 r



18

Każda z tych odpowiedzi ma jedną wspólną cechę: wszystkie przechowują daty jako jedną wartość (zwykle ciąg znaków).

Inną opcją jest skorzystanie z wbudowanej struktury JSON i przedstawienie daty jako listy liczb:

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

Oczywiście musisz upewnić się, że oba końce rozmowy zgadzają się co do formatu (rok, miesiąc, dzień) i które pola mają być datami, ale ma tę zaletę, że całkowicie omija problem daty konwersja na ciąg znaków. To wszystkie liczby - bez żadnych ciągów. Ponadto, korzystając z zamówienia: rok, miesiąc, dzień, można również prawidłowo sortować według daty.

Po prostu myślę tutaj nieszablonowo - data JSON nie musi być przechowywana jako ciąg.

Kolejną zaletą robienia tego w ten sposób jest to, że możesz łatwo (i wydajnie) wybierać wszystkie rekordy dla danego roku lub miesiąca, wykorzystując sposób, w jaki CouchDB obsługuje zapytania o wartości macierzy.


Jest to standardowy format dat w formacie JSON, który jest w formacie RFC 3339.
gnasher729

@gnasher, byłoby miło, ale tak nie jest. Brak odniesień od RFC 7159 do 3339 lub odwrotnie. Nie ma de jure standardowego formatu daty JSON. Wszystko, co pozostało, to de facto standardy, z których każdy ma zalety / wady. To miła cecha standardów.
Marc L.,

17

Publikowanie w niesamowitym wątku:

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

1
Fajny pomysł, ale co jeśli uwzględni się przesunięcie strefy czasowej? Lepiej użyć substr (6) w tym przypadku zamiast plasterka (6, -2) - patrz moja odpowiedź poniżej.
Roy Tinker

17

Aby dodać tutaj inne podejście, „podejście tykania”, które stosuje WCF, jest podatne na problemy ze strefami czasowymi, jeśli nie jesteś wyjątkowo ostrożny, jak opisano tutaj i w innych miejscach. Teraz używam formatu ISO 8601, który odpowiednio obsługuje .NET i JavaScript, który obejmuje przesunięcia stref czasowych. Poniżej znajdują się szczegóły:

W WCF / .NET:

Gdzie CreationDate jest System.DateTime; ToString („o”) używa specyfikatora formatu .NET w obie strony, który generuje ciąg daty zgodny z ISO 8601

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

W JavaScript

Zaraz po pobraniu JSON idę ustawić daty na obiekty JavaSript Date za pomocą konstruktora Date, który akceptuje ciąg dat ISO 8601 ...

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

Gdy masz już datę JavaScript, możesz użyć wszystkich wygodnych i niezawodnych metod Date, takich jak toDateString , toLocaleString itp.


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

Czy istnieje inna opcja bez korzystania z biblioteki jQuery?


To jest nowe pytanie i powinno być zadawane jako własne pytanie, a nie osadzone tutaj.
Spencer Sullivan

11

To może ci również pomóc.

 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

Poniżej znajduje się dość proste rozwiązanie do analizowania dat JSON. Skorzystaj z poniższych funkcji zgodnie z wymaganiami. Musisz tylko przekazać datę JSON formatu pobranego jako parametr do poniższych funkcji:

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

Możesz także skorzystać z biblioteki JavaScript moment.js , która jest przydatna, gdy planujesz radzić sobie z różnymi zlokalizowanymi formatami i wykonywać inne operacje z wartościami dat:

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

Konfigurowanie lokalizacji jest tak proste, jak dodawanie plików konfiguracyjnych (otrzymujesz je na momentjs.com) do projektu i konfigurowanie języka:

moment.lang('de');

9

Mam taką datę:

"/Date(1276290000000+0300)/"

W niektórych przykładach data jest w nieco innych formatach:

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

itp.

Więc wymyśliłem następujący RegExp:

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

a końcowy kod to:

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

Mam nadzieję, że to pomoże.

Aktualizacja: Znalazłem ten link od Microsoft: Jak mogę serializować daty w JSON?

Wygląda na to, że wszyscy tego szukamy.


1
Wymiana Regexp jest powolna ... Znacznie szybciej jest chwycić część całkowitą za pomocą substr (6) i przekazać ją do parseInt () - patrz moja odpowiedź poniżej.
Roy Tinker


9

Sprawdź datę normy ISO; coś takiego:

yyyy.MM.ddThh:mm

Staje się 2008.11.20T22:18.


Według schematu JSON format „data-godzina” odpowiada RFC 3339, sekcja 5.6. Powinieneś więc napisać „rrrr-MM-ddTHH: mm: ssZ” dla dat w GMT lub Z zastąpić strefą czasową jak + hh: mm.
gnasher729

Problem polega na tym, że WCF i inne „stare” serializacje MS JSON nie używają tego formatu i należy to uwzględnić.
Marc L.,

9

To jest frustrujące. Moim rozwiązaniem było przeanalizowanie „/ i /” z wartości wygenerowanej przez JavaScriptSerializer ASP.NET, aby chociaż JSON mógł nie mieć literału daty, nadal jest interpretowany przez przeglądarkę jako data, i tak naprawdę wszystko chcieć:{"myDate":Date(123456789)}

Niestandardowy konwerter JavaScript dla DateTime?

Muszę podkreślić trafność komentarza Roya Tinkera. To nie jest legalne JSON. Jest to brudny, brudny hack na serwerze, aby usunąć problem, zanim stanie się problemem dla JavaScript. Udusi parser JSON. Użyłem go do zejścia z ziemi, ale już go nie używam. Jednak nadal uważam, że najlepszą odpowiedzią jest zmiana sposobu formatowania daty przez serwer, na przykład ISO, jak wspomniano w innym miejscu.


2
To nie jest legalne JSON. Działa tylko podczas ewaluacji za pomocą interpretera JavaScript. Ale jeśli używasz dekodera JSON, dusi się.
Roy Tinker,

1
Zgoda. A gdybym tylko miał do czynienia z jednym kawałkiem danych, nie rozważyłbym tego. Ale jeśli mam do czynienia z obiektem o kilku datach i innych właściwościach, łatwiej jest ewaluować () całość niż wybierać właściwości pojedynczo. Ostatecznie głównym problemem jest brak (prawnej) daty JSON. Do tego czasu jesteśmy kreatywni.
StarTrekRedneck

8

Późny post, ale dla tych, którzy szukali tego postu.

Wyobraź to sobie:

    [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");
    }

Jak widać, używam funkcji C # 3.0 do tworzenia generycznych „Auto”. To trochę leniwe, ale podoba mi się i działa. Tylko uwaga: Profile to niestandardowa klasa, którą stworzyłem dla mojego projektu aplikacji internetowej.


więc za każdym razem, gdy dodajesz nową rolę [Autoryzuj (Role = „Zasoby ludzkie”)], musisz kompilować i wdrażać? wow .... :)
Alex Nolasco

1
Jeśli jest to usługa JSON, przekierowanie wydaje się nieprawidłowe. Zwróciłbym komunikat 404 Nie znaleziono, jeśli klucz wejściowy jest tak nieprawidłowy, że nie można go znaleźć (a także 404, jeśli naprawdę go nie znaleziono). Gdy moi użytkownicy nie są zalogowani, zwracam 403 Zabronione.
Richard Corfield,

Jest to metoda „wielokrotnego użytku”. Na przykład, jeśli chcę uzyskać dane użytkownika z innego widoku, mogę je uzyskać, o ile podam identyfikator. Jeśli jednak identyfikator nie zostanie podany, strona przekieruje do listy użytkowników (Indeks), aby wybrać użytkownika. Potrzebne było proste rozwiązanie dla aplikacji, tak jak mój mózg wtedy to ugotował.
Ray Linder,

8

Do Twojej wiadomości dla każdego, kto używa Pythona po stronie serwera: datetime.datetime (). Ctime () zwraca ciąg, który można natywnie przetwarzać przez „new Date ()”. Oznacza to, że jeśli utworzysz nową instancję datetime.datetime (na przykład z datetime.datetime.now), ciąg może zostać zawarty w ciągu JSON, a następnie ten ciąg może zostać przekazany jako pierwszy argument do konstruktora Date. Nie znalazłem jeszcze żadnych wyjątków, ale też nie testowałem tego zbyt rygorystycznie.


8

Rozwiązanie Mootools:

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

Wymaga mootools-more. Testowane przy użyciu mootools-1.2.3.1-more w Firefox 3.6.3 i IE 7.0.5730.13


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


8

Co jeśli .NET zwróci ...

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

A potem w JavaScript ...

var x = new Date("2013-09-17 15:18:53Z");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.