2011-09-26 52 views
29

Estoy usando Jackson (a través de Spring MVC Annotations) para deserializar un campo en un java.util.Date de JSON. El POST se ve como - {"enrollDate":"2011-09-28T00:00:00.000Z"}, pero cuando el objeto es creado por Spring & Jackson establece la fecha como "2011-09-27 20:00:00".Establecer la zona horaria de Jackson para la deserialización de la fecha

¿Cómo puedo establecer la zona horaria adecuada en Jackson? O si ese no es el problema, ¿cómo envío EST desde el mensaje JSON?

Javascript/jQuery:

var personDataView = { enrollDate : new Date($("#enrollDate").val()), 
         //...other members 
         }; 


$.postJSON('/some/path/', personDataView, function(data){ 
    //... handle the response here 

}); 

JSON Mensaje:

{"enrollDate":"2011-09-28T00:00:00.000Z"}

Controlador de primavera:

@RequestMapping(value="/", method=RequestMethod.POST) 
public @ResponseBody String saveProfile(@RequestBody personDataView persondataView, HttpServletRequest request) 
{ 
     //...dataView has a java.util.Date enrollDate field 
     //...other code 
} 
+2

¿En qué zona horaria estás? Si estás a 4 horas al oeste de UTC estos 2 sellos son equivalentes. – fvu

+0

Estoy en EST. Entonces, ¿por qué Jackson está asumiendo que la hora de llegada que envío es GMT? ¿Debo cambiar mi javascript para publicar la fecha de manera diferente, o cambiar una configuración con Jackson? –

+3

la Z al final de la marca de tiempo es la abreviatura de +00: 00 aka Zulu time aka UTC/GMT. – fvu

Respuesta

1

Su objeto de fecha es probablemente muy bien, desde que envió su fecha codificada en formato ISO con la zona horaria GMT y se encuentra en EST cuando se imprime la fecha.

Tenga en cuenta que los objetos Date realizan la traducción de la zona horaria en el momento en que son impresos. Puede comprobar si su objeto date es correcta con:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
cal.setTime(date); 
System.out.println (cal); 
14

Si realmente quiere Jackson para devolver una cita con otra zona horaria de GMT (y yo mismo tengo varias buenas razones para que, especialmente cuando algunos clientes simplemente don 't llegar a la parte zona horaria) a continuación, que suele hacer:

ObjectMapper mapper = new ObjectMapper(); 
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); 
dateFormat.setTimeZone(TimeZone.getTimeZone("CET")); 
mapper.getSerializationConfig().setDateFormat(dateFormat); 
// ... etc 

no tiene efectos adversos sobre los que comprenden la zona horaria-p

+11

Parece que mapper.getSerializationConfig(). SetDateFormat (dateFormat) está obsoleto ahora y la nueva forma de hacerlo es mapper.setDateFormat (dateFormat) – Tim

3

estoy usando Jackson 1.9.7 y me encontré con que hacer lo siguiente no resuelve mi serialización/des erialization problema zona horaria:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ"); 
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
objectMapper.setDateFormat(dateFormat); 

En lugar de "2014-02-13T20: 09: 09.859Z" Me "2014-02-13T08: 09: 09,859 + 0000" en el mensaje JSON que es obviamente incorrecto. No tengo tiempo para pasar por el código fuente de la biblioteca Jackson para descubrir por qué ocurre esto, sin embargo, descubrí que si solo especifico la clase Jackson ISO8601DateFormat con el método ObjectMapper.setDateFormat, la fecha es correcta.

Excepto esto no pone los milisegundos en el formato que es lo que quiero, así que subclasificado la clase y ISO8601DateFormat hizo caso omiso del método format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) .

/** 
* Provides a ISO8601 date format implementation that includes milliseconds 
* 
*/ 
public class ISO8601DateFormatWithMillis extends ISO8601DateFormat { 

    /** 
    * For serialization 
    */ 
    private static final long serialVersionUID = 2672976499021731672L; 


    @Override 
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) 
    { 
     String value = ISO8601Utils.format(date, true); 
     toAppendTo.append(value); 
     return toAppendTo; 
    } 
} 
+0

El resultado coincide exactamente con el SimpleDateFormat que le asignó. Por [SimpleDateFormat Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html): salidas de hh 12 horas de tiempo, kk salidas 24 horas y Z salidas de la zona horaria de desplazamiento . Creo que querías un formato de fecha explícito de 'aaaa-MM-dd'T'kk: mm: ss.SSS'Z''. – kaliatech

+0

El formato de la fecha era un problema menor, el principal problema para mí era que los valores de fecha reales que escupía ObjectMapper eran incorrectos. Mire cuidadosamente el ejemplo que di, la fecha de salida fue en realidad 12 horas fuera de lo esperado, es decir, en lugar de "2014-02-13T20: 09: 09.859Z" recibí "2014-02-13T08: 09: 09.859 +0000 " – whitestryder

+0

08:09:09 en _12_ hora hora (con el indicador am/pm faltante) es equivalente a 20:09:09 en _24_ hora hora. – kaliatech

1

Tuve el mismo problema con la deserialización del calendario, solucioné extendiendo CalendarDeserializer.
Obliga zona UTC
me pega el código si alguien lo necesita:

@JacksonStdImpl 
public class UtcCalendarDeserializer extends CalendarDeserializer { 

    TimeZone TZ_UTC = TimeZone.getTimeZone("UTC"); 

    @Override 
    public Calendar deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     JsonToken t = jp.getCurrentToken(); 
     if (t == JsonToken.VALUE_NUMBER_INT) { 
      Calendar cal = Calendar.getInstance(TZ_UTC); 
      cal.clear(); 
      cal.setTimeInMillis(jp.getLongValue()); 

      return cal; 
     } 

     return super.deserialize(jp, ctxt); 
    } 
} 

en la clase de modelo de JSON simplemente anotar el campo con:

@JsonDeserialize(using = UtcCalendarDeserializer.class) 
private Calendar myCalendar; 
23

En 2+ Jackson, también se puede utilizar la anotación @JsonFormat:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone="America/Phoenix") 
private Date date; 
+1

@JsonFormat (shape = JsonFormat.Shape.STRING, patrón = "aaaa-MM-dd'T'HH: mm: ss.SSSZ", zona horaria = "US/Arizona") –

0

acaba de llegar a este tema y finalmente se dio cuenta de que LocalDateTime no tiene información de zona horaria. Si ha recibido una cadena de fecha con la información de zona horaria, es necesario utilizar esto como el tipo:

ZonedDateTime

Marque esta link

0

¿Has probado esto en sus application.properties?

spring.jackson.time-zone= # Time zone used when formatting dates. For instance `America/Los_Angeles` 
Cuestiones relacionadas