2012-02-08 18 views
8
{ id: 1533, 
    story_type_id: 1, 
    content_id: 470, 
    created_at: Sun, 05 Feb 2012 07:02:43 GMT, 
    updated_at: Sun, 05 Feb 2012 07:02:43 GMT, 
    type_name: 'post' } 

Tengo un objeto JSON con el campo "datetime" como en el ejemplo anterior. Es perfecto. Pero cuando stringify (yo quiero para almacenarlo en caché), consigo este formato:¿Por qué JSON.stringify arruina mi objeto datetime?

"created_at":"2012-02-05T07:02:43.000Z" 

Esto causa problemas, porque cuando quiero JSON.parse esto, de repente ya no es de fecha y hora formato y es incompatible con mi otro formato.

¿Qué puedo hacer para resolver este problema? He 'created_at' en todas partes de mi aplicación. No quiero cambiar manualmente cada uno.

+0

Presumiblemente está serializando estas fechas para almacenarlas en localStorage. En ese caso, puedes evitar un aggro como este y similar usando una biblioteca contenedora como rhaboo. –

Respuesta

13

No hay forma especial de serializar objetos Date en JSON. Es por eso que obtienes la representación de cadena estandarizada. Debe convertirlos de nuevo a objetos Date pasándolos al constructor Date.

item['created_at'] = new Date(item['created_at']); 

Actualización: Con la función reviver (ver comentarios), puede obtener los objetos Date espalda.

var item = JSON.parse(row, function (key, value) { 
    if (key === 'created_at') { 
    return new Date(value); 
    } else { 
    return value; 
    } 
}); 
+0

¿No hay nada que pueda hacer al respecto? – TIMEX

+0

No, no lo creo. Deberías almacenarlo de otra manera. –

+0

El objeto 'Fecha' es nativo de JavaScript, pero JSON es un mecanismo de serialización utilizado para transportar datos entre plataformas. Si permitiera la serialización de objetos y funciones nativas, los sistemas que transmiten JSON de JS a, digamos, PHP se romperían. Es posible que desee examinar las metodologías JSON 'reviver'. – JAAulde

10

En realidad, es posible modificar cómo un objeto Date se serializará en JSON. Combinado con la función reviver, se puede crear una solución bidireccional que funcionará automáticamente en la serialización y se puede usar fácilmente en la deserialización.

En primer lugar modificar la serialización de esta manera:

Date.prototype.toJSON = function() { return "{timestamp}+" . this.getTime() } 

Esto cambiará la representación de un objeto Date en una marca de tiempo UNIX con un prefijo como marcador:

> json = JSON.stringify({test:new Date()}); 
"{"test":"{timestamp}1380164268633"}" 

continuación, puede crear una Función reviver que filtrará automáticamente estos valores:

function json_deserialize_helper(key,value) { 
    if (typeof value === 'string') { 
    var regexp; 
    regexp = /^{timestamp}(\d*)$/.exec(value); 
    if (regexp) { 
     return new Date(+regexp[1]); 
    } 
    } 
    return value; 
} 

(Crédito Este código fue básicamente copiado de esta respuesta en una pregunta relacionada: https://stackoverflow.com/a/14509447/2572897)

Ahora, con esta configuración, deserialización de nuestro resultado de delante se traducirá en un objeto Date de nuevo:

> JSON.parse(json, json_deserialize_helper); 
Object {test: Thu Sep 26 2013 04:57:48 GMT+0200 (CEST)} 

o puede elegir no modificar la serialización, pero en lugar de utilizar la expresión regular para coger el formato de serialización estándar:

function json_deserialize_helper(key,value) { 
    if (typeof value === 'string') { 
    var regexp; 
    regexp = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/.exec(value); 
    if (regexp) { 
     return new Date(value); 
    } 
    } 
    return value; 
} 

Ejemplo:

> json = JSON.stringify({test:new Date()}) 
"{"test":"2013-09-26T03:05:26.563Z"}" 
> JSON.parse(json, json_deserialize_helper) 
Object {test: Thu Sep 26 2013 05:05:26 GMT+0200 (CEST)} 
0

Date.prototype.toJSON = function() {return moment (this) .format ('L'); }

Puede obtener más información sobre la documentación de momentos y el tipo de fecha que desea devolver.

Cuestiones relacionadas