util type deserialize cannot java datetime jackson deserialization jodatime

type - jsonobject date format java



Zona horaria predeterminada para deserialización de DateTime con Jackson(módulo Joda-Time) (4)

UTC versus GMT

Para aplicaciones de negocios, no hay una diferencia práctica entre UTC y GMT . La única diferencia se relaciona con la resolución de un segundo y un segundo de Leap agregado cada varios años. Para la ciencia, la astronomía, el rastreo satelital y tales aplicaciones, la diferencia puede ser significativa, pero eso es raro.

Jackson está por defecto en UTC / GMT

No conozco a Jackson . Pero al mirar el documento que vinculó, parece que se serializan (a) el número de milisegundos desde el 1 de enero de 1970, UTC o (b) un formato de cadena, el formato predeterminado es ISO 8601 : "1970-01- 01T00: 00: 00.000 + 0000 ". Entonces, para responder a su pregunta sobre las zonas horarias, parece que, de manera predeterminada, Jackson siempre se serializa usando UTC (sin desplazamiento de zona horaria), que es la forma correcta de hacerlo. Si le importa la zona horaria que estaba en uso en ese momento, debe registrar ese hecho (qué zona horaria) en un campo separado.

Jackson ↔ java.util.Date/Calendar ↔ Joda-Time

Ambos valores serializados (milisegundos y cadena ISO 8601) se pueden usar con constructores para instancias de Joda-Time DateTime .

String dateTimeString = "2013-11-22T18:37:55.645+0000"; org.joda.time.DateTime myDateTime = org.joda.time.format.ISODateTimeFormat.dateTime().withZoneUTC().parseDateTime( dateTimeString );

y…

Long millisSinceEpoch = 1385495462L; org.joda.time.DateTime myDateTime = new org.joda.time.DateTime( millisSinceEpoch );

Si no tiene acceso directo a esos valores serializados para alimentar a los constructores de Joda-Time DateTime, deje que Jackson cree instancias de los objetos java.util.Date/Calendar. Alimente esos objetos java.util.Date/Calendar a Joda-Time para crear una instancia de los objetos DateTime para trabajo adicional. Los usuarios de Joda-Time hacen esto comúnmente.

org.joda.time.DateTime myDateTime = new org.joda.time.DateTime( someJavaUtilDateFromJackson );

Puede convertir fácilmente esa hora UTC a otras zonas horarias en Joda-Time llamando al método toDateTime() y pasando la zona horaria deseada.

org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" ); org.joda.time.DateTime dateTimeInKolkata = myDateTime.toDateTime( kolkataTimeZone );

Joda-Time se convierte fácilmente a java.util.Date utilizando el método toDate . Haga la mayor parte de su trabajo en Joda-Time y conviértalo de nuevo a java.util.Date para comunicarse con Jackson. Y cuando volviera a Jackson, cambiaría mis DateTimes de nuevo a UTC solo por si acaso.

myDateTime.toDateTime( org.joda.time.DateTimeZone.UTC )

Encontrará muchos ejemplos de las operaciones de Joda-Time mencionadas anteriormente en StackOverflow.com.

Simplemente hazlo

Sospecho que te estás preocupando demasiado y no tienes suficiente codificación. Solo intente algunos pequeños experimentos pasando valores dentro y fuera de Jackson y Joda-Time. Rápidamente te dominarás. Te recomiendo que dejes que Jackson haga lo que quiera hacer por defecto y luego manipule en Joda-Time. Joda-Time está diseñado para los problemas geniales de la fecha y la hora, y Jackson, presumiblemente, no. Joda-Time tiene tanto constructores como métodos para ajustar entre zonas horarias según lo deseado.

Un futuro más brillante

En Java 8, JSR 310: API de fecha y hora trae clases similares a Joda-Time integradas en la plataforma Java. Espere ver marcos como Jackson actualizados para trabajar directamente con esas nuevas clases mientras se desaprueban las clases java.util.Date/Calendar.

Parece que el proyecto jackson-datatype-joda está tratando de brindarte ese tipo de conveniencia ahora para Joda-Time. Pero no me parece necesario. Usted podría simplemente convertir entre java.util.Date/Calendar y Joda-Time como se discutió anteriormente.

PS El enlace "Wiki" para la documentación de ese proyecto falla. Así que no pude mirar su doc.

Esta pregunta es sobre la deserialización a Joda-Time DateTime usando el módulo jackson-datatype-joda para Jackson . ¿Hay una zona horaria predeterminada en la que se deserializarán las cadenas de fecha? Si es así, ¿qué es? ¿Es UTC ?

Necesito preguntar esto porque la documentación de Jackson no es específica para Joda-Time DateTime. Encontré en este artículo ( http://wiki.fasterxml.com/JacksonFAQDateHandling ) que Jackson asumirá GMT como la zona horaria predeterminada para deserializar en java.util.Date o java.util.Calendar . Sin embargo, no se mencionan los tipos de datos de Joda-Time en este documento. Además, necesito específicamente cadenas para deserializar en objetos DateTime usando la zona horaria UTC , no GMT: aunque estas dos zonas son muy similares, hay algunas pequeñas diferencias y, por lo tanto, GMT no será factible para mí.

Gracias.


A partir de un código simple, descubrí que cuando Jackson deserializa al objeto Fecha de la cadena, da UTC si no se menciona ninguna zona horaria, pero cuando se crea una instancia directamente, da la zona horaria predeterminada, es decir, la zona horaria de la máquina.

DateTime date = new DateTime(2013, 1, 2, 0, 0) //gives local timezone

Siguiendo da UTC

ObjectMapper mapper = new ObjectMapper(); DateTime dt = new DateTime(2013, 1, 2, 0, 0); String serialized = mapper.writeValueAsString(dt); DateTime dt1 = mapper.readValue(serialized, DateTime.class); //gives UTC


El código fuente de DateTimeDeserializer muestra que usa la zona horaria de DeserializationContext que proporciona ObjectMapper durante la deserialización. Si observa la API de ObjectMapper , verá que hay un método para configurar la zona horaria:

public ObjectMapper setTimeZone(TimeZone tz)

Por lo tanto, puede utilizar este método para configurar su ObjectMapper y establecer la zona horaria en la correcta.

Por lo que respecta al valor predeterminado, parece que el Javadoc dice una cosa, pero el código muestra otra.

Javadoc para ObjectMapper.setTimeZone(TimeZone tz) :

/** * Method for overriding default TimeZone to use for formatting. * Default value used is {@link TimeZone#getDefault()}. */

Sin embargo, el código establece la zona horaria explícitamente en:

protected final static BaseSettings DEFAULT_BASE = new BaseSettings( ... // TimeZone.getDefault() TimeZone.getTimeZone("GMT"), ...

Entonces, al parecer, en realidad utiliza GMT, y no el valor predeterminado predeterminado de JVM.

Yo diría que probablemente la mejor opción sería no confiar en esto y configurarlo por sí mismo en ObjectMapper.setTimeZone(TimeZone tz) .


También luché con los formatos de fecha y finalmente encontré la solución. Quería usar el formato "2016-02-08T12:49:22.876Z" ya que es ISO 8601 y es utilizado por el objeto Date JavaScript. También quise usar siempre la zona horaria UTC.

Encontré que esto se puede hacer usando el siguiente código:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd''T''HH:mm:ss.SSSX"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); final ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(dateFormat); System.out.println(objectMapper.writeValueAsString(new Date()));

Tenga en cuenta el carácter X en la cadena de formato. Es compatible con Java 7 y especifica la zona horaria en ISO 8601. Como se documenta en SimpleDateFormat , produce Z (en lugar de +00:00 ) si el desplazamiento de la zona horaria es 0 (UTC).