2008-09-17 29 views
35

Biorąc pod uwagę następujące JSON Data reprezentacja:deserializacji Client-Side AJAX JSON Daty

"\/Date(1221644506800-0700)\/" 

Jak deserializować to pod nim znajduje JavaScript forma Data typu?

Próbowałem przy użyciu MS AJAX JavaScrioptSerializer jak pokazano poniżej:

Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/") 

Jednak wszystkie wrócę to dosłowne data ciąg.

+0

używasz jQuery może? Sprawdź mój wpis na blogu, aby automatycznie konwertować daty, więc nie musisz tego robić ręcznie. http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html –

+0

Zobacz moje komentarze poniżej. Twój kod bloga kończy się niepowodzeniem w datach sprzed epoki. –

Odpowiedz

28

Pod warunkiem, że wiemy, że ciąg jest zdecydowanie data Wolę to zrobić:

new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10)) 
+0

To zadziałało dla mnie, moja metoda ToJson serializowała DateTimes jako "\/Date (1251795081950) \ /" – CVertex

+2

Dziękuję ty. 'var date = new Data (parseInt (jsonDate.substr (6)));' działa również. –

1

Duża liczba jest standardowy czas JS

new Date(1221644506800) 

Wed 17 września 2008 19:41:46 GMT + 1000 (CET)

10
wartość

JSON jest ciągiem znaków, liczba, obiekt, tablica , true, false lub null. To jest tylko ciąg znaków. Nie ma oficjalnego sposobu reprezentowania dat w JSON. Ta składnia pochodzi z implementacji asp.net ajax. Inni używają formatu ISO 8601.

można analizować to tak:

var s = "\/Date(1221644506800-0700)\/"; 
var m = s.match(/^\/Date\((\d+)([-+]\d\d)(\d\d)\)\/$/); 
var date = null; 
if (m) 
    date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]); 
+0

To nie zadziałało dla mnie – CVertex

+0

Moja metoda toJson wypluła zserializowane daty jako "\/Data (1251795070160) \ /", której twój kod nie analizuje. Zastanowię się, dlaczego później, po prostu publikuję tutaj dla innych – CVertex

+0

+1, aby wyjaśnić, czym może być wartość JSON, a daty nie są jednym z nich, ale niestandardowym formatem. –

5

Wyrażenie regularne używane w metodzie deserializowania ASP.net AJAX wygląda na sznurku, który wygląda jak „/ data (1234) /” (The samej rzeczywistości ciąg musi zawierać cudzysłowy i ukośniki). Aby uzyskać taki ciąg, będziesz musiał uciec przed cudzysłowami i znakami ukośnika, aby kod javascript do utworzenia ciągu wyglądał jak "\" \/Data (1234) \/\ "".

To zadziała.

Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800)\\/\"") 

To trochę dziwne, ale uważam, że miałem do serializacji datę, a następnie serializować ciąg zwrócony z tego, to deserializowania po stronie klienta raz.

Coś takiego.

Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer(); 
string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now))); 
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true); 
+0

Problem z tym Metoda polega na tym, że nie wygląda ona w strefie czasowej: Sys.Serialization.JavaScriptSerializer.deserialize ("\" \\/Date (1221644506800 + 0200) \\/\ "") Czy wyniki będą takie same jak: Sys. Serializacja.JavaScriptSerializer.deserialize ("\" \\/Data (1221644506800 + 0300) \\/\ "") –

3

dla tych, którzy nie chcą korzystać z programu Microsoft Ajax, wystarczy dodać funkcję prototypu do klasy String .

E.g.

String.prototype.dateFromJSON = function() { 
    return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date($1)")); 
}; 

Nie chcesz używać eval? Wypróbuj coś prostego, jak na przykład: Na marginesie, uważałem, że Microsoft wprowadzał w błąd przy użyciu tego formatu. Jednak specyfikacja JSON nie jest zbyt jasna, jeśli chodzi o definiowanie sposobu opisywania dat w JSON.

+2

To wyrażenie nie będzie działać dla dat sprzed epoki, które mają wartość ujemną. Potrzebujesz tego: '/ \/Date \ ((?? D +) (?: - \ d +)? \) \ // i' –

16

Bertrand LeRoy, który pracował przy ASP.NET Atlas/AJAX, described the design of the JavaScriptSerializer DateTime output i ujawnił pochodzenie tajemniczych wiodących i ciągnących ukośników.Zrobił to zalecenie:

uruchomić prosty wyszukiwania dla "\/Date ((\ d +)) \ /" i zastąpić "new Date ($ 1)" przed eval (ale po zatwierdzeniu)

I wdrożone że jako:

var serializedDateTime = "\/Date(1271389496563)\/"; 
document.writeln("Serialized: " + serializedDateTime + "<br />"); 

var toDateRe = new RegExp("^/Date\\((\\d+)\\)/$"); 
function toDate(s) { 
    if (!s) { 
     return null; 
    } 
    var constructor = s.replace(toDateRe, "new Date($1)"); 
    if (constructor == s) { 
     throw 'Invalid serialized DateTime value: "' + s + '"'; 
    } 
    return eval(constructor); 
} 

document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />"); 

to jest bardzo blisko do wielu innych odpowiedzi:

  • Użyj zakotwiczonego RegEx, jak zrobił to Sjoerd Visscher - nie zapomnij o^i $.
  • Unikaj ciągu znaków string.replace, a opcji "g" lub "i" w formularzu RegEx. "/ Date (1271389496563) // Data (1271389496563) /" nie powinna działać w ogóle.
+1

Bardzo dobra odpowiedź .... hańba znalazłem ją na dole lista pytań. – GordonB

+6

To wyrażenie nie będzie działać dla dat sprzed epoki, które mają wartość ujemną. Potrzebujesz czegoś takiego: '/ \/Date \ ((-? \ D +) (?: - \ d +)? \) \ // i'' –

1

Właściwie momentjs obsługuje tego formatu, można zrobić coś takiego:

var momentValue = moment(value); 

    momentValue.toDate(); 

ta zwraca wartość w javascript formatu daty