2016-07-29 3 views
1

С Spring MVC (Spring загрузочном) Я десериализацией ZonedDateTime отДжексон: синтаксический ZonedDateTime с часовым поясом ID

2016-07-26T05:30:47+01:00 

, но не от

2016-07-26T05:30:47+01:00 Europe/Paris 

Как я могу явно добавить часовой пояс и все еще быть в состоянии десериализировать его?

+0

Термин «Европа/Париж» обозначает полный часовой пояс, включая любые истории перехода, фактические и будущие правила перехода на летнее время и версию базовых данных о часовом поясе. Поэтому сериализация и десериализация потенциально потребовали бы передать все это, а не только строку «Европа/Париж». На мой взгляд, сериализовать все не рекомендуется. Рассматривали ли вы только сериализацию момента «ZonedDateTime», обеспечивающего лучшую производительность? –

ответ

0

Вы можете указать шаблон с необязательным разделом (с разделителем []), чтобы указать, что какое-либо поле является необязательным, и добавьте его в соответствующее поле, используя аннотацию @JsonFormat.

Например, возьмем этот класс:

public class OptionalTimeZoneTest { 

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX[ VV]") 
    private ZonedDateTime date; 

    // getter and setter 
} 

Обратите внимание на последнюю часть ([ VV]): шаблон внутри [] является необязательным раздел, поэтому анализатор пытается разобрать его, если он присутствует. И картина VV является зона идентификатор (или имя часового пояса в, для получения более подробной информации, посмотрите на javadoc)

С этим, в обоих форматах можно прочитать:

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new JavaTimeModule()); 
// add this to preserve the same offset (don't convert to UTC) 
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

// without timezone 
String json = "{ \"date\": \"2016-07-26T05:30:47+01:00\" }"; 
OptionalTimeZoneTest value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+01:00 

// with timezone 
json = "{ \"date\": \"2016-07-26T05:30:47+01:00 Europe/Paris\" }"; 
value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+02:00[Europe/Paris] 

Выход:

2016-07-26T05: 30: 47 + 01: 00
2016-07-26T05: 30: 47 + 02: 00 [Европа/Париж]

Обратите внимание, что в первом случае выход равен 2016-07-26T05:30:47+01:00 (поскольку он не имеет часовой пояс, поэтому применяется смещение +01:00).

Но во втором случае выход 2016-07-26T05:30:47+02:00[Europe/Paris], потому что в Europe/Paris часовом поясе, 26/07/2016 is summer-time (так что смещение является +02:00). И API java.time были реализованы таким образом, что временная зона имеет преимущество при анализе такого String.


Если вы хотите, чтобы все ZonedDateTime экземпляров должны быть преобразованы в UTC, вы можете удалить эту строку:

mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

Без него дата будет преобразована в UTC, а на выходе будет:

2016-07-26T04: 30: 47Z [UTC]
2016-07-26T03: 30: 47Z [UTC]