2012-01-18 47 views
14

Tengo un objeto JavaScript con Fecha propiedad que se convierte en JSON usando JSON.stringifyJavascript y Java serialización Fecha JSON

estoy en +4 zona horaria GMT (Rusia/Moscú)

Por ejemplo , 5 Jan 2012 convierte a 2012-01-04T20:00:00.000Z

5 Jan 1975 convierte a 1975-01-04T20:00:00.000Z

Pero en 1975 fue GMT + 3 zona horaria, como el horario de verano fue cancelada en Rusia en 2011. Así que cuando se cames al servidor (Java) se deserializa como:

2012-01-04T20:00:00.000Z becames 5 Jan 2012 00:00 - OK

1975-01-04T20:00:00.000Z becames 4 Jan 1975 23:00 - ¡EQUIVOCADO!

¿Cuál es la forma recomendada de convertir el objeto Date a JSON en Javascript?

+0

Esto podría ser útil. Tal vez incluso un posible duplicado: http://stackoverflow.com/questions/4032967/json-date-to-java-date – Johan

Respuesta

12

Sugeriría pasar la fecha/horas usando sus segundos desde la notación de época, más específicamente la cantidad de segundos desde la Época de Unix (1 de enero de 1970 a las 00:00 GMT). Si usted no está familiarizado con esto, hay un convertidor de ejemplo aquí: http://www.epochconverter.com/

Esto tiene algunas ventajas:

  • Se refiere al mismo momento en el tiempo, independientemente de la zona horaria. Esto ayuda a almacenar el tiempo independientemente de los errores de zona horaria (aunque, por supuesto, tendrían que ser ingresados ​​correctamente en primer lugar, por supuesto).
  • Es el único constructor no en desuso (excepto el constructor sin params) en java.util.Date, ver (getTime() también). (Tenga en cuenta que esto utiliza milisegundos.)
  • JavaScript puede crear una fecha fácilmente (por ejemplo, new Date(1000 * 1326894706)). (Tenga en cuenta que esto utiliza milisegundos.)
  • Si es importante, siempre va a ser un poco más pequeño (en términos de tamaño de datos en su serialización JSON) que cualquiera de "yyyy-MM-dd HH:mm:ss".
  • Si desea que se represente la zona horaria y se asocie con este número, siempre puede agregar un campo adicional a su representación. { "datetime": 1326894706, "tz": "GMT" } es aún más corto que { "datetime": "18 Jan 2012 13:51:46 GMT" }.

Teniendo en cuenta que es fácil de conseguir Date casos de esto en Java y JavaScript, a continuación, puede utilizar un DateFormatter para convertirlo a/de texto en Java. Para JavaScript, usar una biblioteca como Date Format lo ayudará a representarlo como corresponda en la página (por ejemplo, con algo como new Date(val * 1000).format("yyyy-mm-dd HH:MM")).

+0

Investigué un poco más y descubrí que epoch se trata de manera diferente en java y javascript (http://stackoverflow.com/questions/8913059/javascript-date-and-java-util-date-constructor-argument). Si no puedo confiar en el método getTime(), no tengo idea de cómo usar el tiempo de época. – ike3

+0

Solo se comportan de forma diferente en la forma en que vinculan la zona horaria a su ubicación en ese momento. Pensé que tu entrada eran (correctas) instancias JS 'Date' en primer lugar? ¿Cómo los construyes? ¿Puedes mostrar un ejemplo de cómo se produjo el '5 de enero de 1975' inicialmente? – Bruno

+0

Obtengo Fecha de jQuery DatePicker $ ("date"). DatePicker ("getTime") cuando se elige el 5 de enero de 1975 en el calendario. Luego se serializa a JSON usando JSON.stringify, que usa 4 horas de diferencia de manera independiente en el año. Pero Java sabe que antes de 2011 era GMT + 3 y lo deserializa de la manera correcta, así que obtengo una diferencia de 1 hora para las fechas anteriores a 2011 – ike3

0

personalmente me convertirlos en cadena en Java usando algo como esto:

String theDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); 

Y a continuación, la cadena es serializado. En el lado de javascript, simplemente analiza eso.

+0

Creo que el problema va * de * JavaScript * a * Java. – Pointy

+0

O al revés: stringify en Javascript para analizar en Java, ya que el autor quiere Javascript-> Java, si leo la pregunta correctamente. – Zlatko

+0

Sí, estoy pensando en escribir el serializador/deserializador de fechas personalizado para Spring MVC + Jackson. – ike3

0

JSON no tiene soporte de fecha, todos los analizadores/serializadores usan el toString o algo así.Depende de usted serializar/deserializar las fechas.
Dado que Javascript no tiene un formateador de fecha decente incluido, la solución más simple es transformar la fecha en larga. Pero si usted quiere ser capaz de leer lo que está pasando, recomiendo http://www.datejs.com/ y dar formato a fechas como aaaa-MM-dd hh: mm: ss

13

prefiero que se adhieren a los javascript ISO 8601 formato de fecha, cuando analizarlo correctamente, manejará automáticamente las diferencias de zona horaria.

en Java puede analizar una fecha Javascript Stringified JSON de la siguiente manera:

String iso8601Date = "2013-08-13T14:15:00.000Z"; 
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); 
Date parsedDate = formatter.parse(iso8601Date); 

Al girar de nuevo en las cuerdas, tendrás algo como esto

//"2013-08-13T16:15:00.000+02:00" 
String formattedDate = formatter.format(parsedDate); 

para analizar JSON utilizo FlexJson, que puedes configurar así.

//Serializing to JSON 
DateTransformer dateTransformer = new DateTransformer("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); 
new JSONSerializer().transform(dateTransformer, Date.class).serialize(object); 
//deserialize From JSON (replace object by java class) 
JSONDeserializer<..Object..>().use(Date.class, dateTransformer).deserialize(json); 
+0

+1. Gracias por "aaaa-MM-dd'T'HH: mm: ss.SSSXXX" :) – TheKojuEffect

1

Si utiliza Spring Framework puede utilizar el @JsonSerialize(using = CustomLocalDateSerializer.class) y @JsonDeserialize(using = ISO8601LocalDateDeserializer.class) anotación. Analizará correctamente su javascript Date.

Ejemplo:

public class product { 

    @NotNull 
    private Long id; 

    @NotNull 
    private String name; 

    @JsonSerialize(using = CustomLocalDateSerializer.class) 
    @JsonDeserialize(using = ISO8601LocalDateDeserializer.class) 
    private LocalDate date; 

    // getter and setter... 
} 
Cuestiones relacionadas