2008-09-17 7 views
35

Dada la siguiente JSON Fecha representación:deserializar del lado del cliente AJAX JSON Fechas

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

¿Cómo se Deserialize esto en su forma de tipo JavaScript Fecha?

He intentado usar MS AJAX JavaScrioptSerializer como se muestra a continuación:

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

Sin embargo, todo lo que se obtiene es la fecha de cadena literal.

+0

¿Está utilizando jQuery tal vez? Verifique la publicación de mi blog para convertir automáticamente las fechas para que no tenga que hacerlo manualmente. http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html –

+0

Ver mis comentarios a continuación. El código de tu blog falla en las fechas anteriores a la época. –

Respuesta

28

siempre y cuando sepas la cadena es sin duda una fecha Prefiero hacer esto:

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

Esto funcionó para mí, mi método ToJson estaba serializando DateTimes como "\/Date (1251795081950) \ /" – CVertex

+2

Gracias tú. 'var date = new Date (parseInt (jsonDate.substr (6)));' funciona también. –

1

El número grande es el tiempo estándar JS

new Date(1221644506800) 

Mié Sep 17 2008 19:41:46 GMT + 1000 (EST)

10
valor

A JSON es una cadena, número, objeto, matriz , verdadero, falso o nulo. Entonces esto es solo una cadena. No hay forma oficial de representar fechas en JSON. Esta sintaxis es de la implementación asp.net ajax. Otros usan el formato ISO 8601.

Puede analizar de esta manera:

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

Esto no funcionó para mí – CVertex

+0

Mi método toJson estaba escupiendo fechas serializadas como "\/Date (1251795070160) \ /", que su código no analiza. Voy a averiguar por qué más tarde, solo publicando aquí para los demás – CVertex

+0

+1 para dejar en claro qué valor JSON puede ser y que las fechas no son una de ellas, sino un formato personalizado. –

5

La expresión regular utilizada en el método deserializar ASP.net AJAX busca una cadena que se parece a "/ Fecha (1234) /" (la propia cadena realidad necesita contener las comillas y las barras). Para obtener una cadena de este tipo, deberá escapar de los caracteres de comillas y barras diagonales, por lo que el código de JavaScript para crear la cadena se ve como "\" \/Fecha (1234) \/\ "".

Esto funcionará.

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

Es un poco raro, pero me encontré con que tenía para serializar una fecha, a continuación, serializar la cadena devuelta de eso, a continuación, deserializar en el lado cliente una vez.

Algo como esto.

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

El problema con esto método es que no mira en la zona horaria: Sys.Serialization.JavaScriptSerializer.deserialize ("\" \\/Date (1221644506800 + 0200) \\/\ "") Será el mismo resultado que: Sys. Serialization.JavaScriptSerializer.deserialize ("\" \\/Date (1221644506800 + 0300) \\/\ "") –

3

Para aquellos que no quieran utilizar Microsoft Ajax, basta con añadir una función prototipo de la clase string .

E.g.

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

¿No quieres usar eval? Probar algo tan simple como

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

Como nota al margen, yo solía pensar que Microsoft era engañosa mediante el uso de este formato. Sin embargo, la especificación JSON no es muy clara cuando se trata de definir una forma de describir las fechas en JSON.

+2

Esa expresión regular no funcionará para las fechas anteriores a la época, que tienen un valor negativo. Necesitas esto: '/ \/Date \ ((-? \ D +) (?: - \ d +)? \) \ // i' –

16

Bertrand LeRoy, que trabajó en ASP.NET Atlas/AJAX, described the design of the JavaScriptSerializer DateTime output y reveló el origen de las misteriosas barras delanteras principales y posteriores.Él hizo esta recomendación:

plazo una simple búsqueda de "\/fecha ((\ d +)) \ /" y sustituir por "new Date ($ 1)" antes de la eval (pero después de la validación)

implementé que a medida:

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 />"); 

Esto es muy cerca de la muchas de las otras respuestas:

  • Use un RegEx anclado como lo hizo Sjoerd Visscher, no olvide el^y $.
  • Evite string.replace, y las opciones 'g' o 'i' en su RegEx. "/ Fecha (1271389496563) // Fecha (1271389496563) /" no debería funcionar en absoluto.
+1

Una muy buena respuesta ... lástima que la encontré en la parte inferior lista para la pregunta – GordonB

+6

Esa expresión regular no funcionará para las fechas anteriores a la época, que tienen un valor negativo. Necesitas algo como esto: '/ \/Date \ ((-? \ D +) (?: - \ d +)? \) \ // i' –

1

En realidad, momentjs apoya este tipo de formato, es posible hacer algo como:

var momentValue = moment(value); 

    momentValue.toDate(); 

Esto devuelve el valor en un formato de fecha Javascript

Cuestiones relacionadas