Reputation: 741
I have multiple timezones and I want to have them exactly after serialization, but jackson
convert them into single time zone if I set DateFormat
all zones convert to context time zone and if I don't set DateFormat
all zones convert to UTC
(zero time zone).
I know that we have DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
in deserialization and we can disable it but I can't find something like this in SerializationFeature
.
Is there anyway that I can tell jackson
to don't convert timezones?
here is my test class:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class Test {
public static class flight {
private XMLGregorianCalendar dateDeparture;
private XMLGregorianCalendar dateArrival;
public XMLGregorianCalendar getDateDeparture() {
return dateDeparture;
}
public void setDateDeparture(XMLGregorianCalendar dateDeparture) {
this.dateDeparture = dateDeparture;
}
public XMLGregorianCalendar getDateArrival() {
return dateArrival;
}
public void setDateArrival(XMLGregorianCalendar dateArrival) {
this.dateArrival = dateArrival;
}
}
public static void main(String[] args) throws DatatypeConfigurationException, JsonProcessingException {
XMLGregorianCalendar dateDeparture = DatatypeFactory.newInstance().newXMLGregorianCalendar(2018,1,22,10,15,0,0, TimeZone.getTimeZone("Asia/Istanbul").getRawOffset()/1000/60);
XMLGregorianCalendar dateArrival = DatatypeFactory.newInstance().newXMLGregorianCalendar(2018,1,22,13,30,0,0,TimeZone.getTimeZone("Asia/Dubai").getRawOffset()/1000/60);
System.out.println("Local Departure Time=" + dateDeparture);
System.out.println("Local Arrival Time=" + dateArrival);
flight flight = new flight();
flight.setDateDeparture(dateDeparture);
flight.setDateArrival(dateArrival);
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
xmlMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ"));
String xml = xmlMapper.writeValueAsString(flight);
System.out.println(xml);
}
}
here is the output:
Local Departure Time=2018-01-22T10:15:00.000+03:00
Local Arrival Time=2018-01-22T13:30:00.000+04:00
<flight><dateDeparture>2018-01-22T10:45:00+0330</dateDeparture><dateArrival>2018-01-22T01:00:00+0330</dateArrival></flight>
Upvotes: 1
Views: 1240
Reputation: 450
The only way I could think of is to create your own serialize module so to be able to handle XMLGregorianCalendar
serialization all by yourself. Unfortunately Java has proven not to be good in handling dates.
public class XMLCalendarSerializer extends StdSerializer<XMLGregorianCalendar> {
public XMLCalendarSerializer() {
this((Class)null);
}
public XMLCalendarSerializer(Class<XMLGregorianCalendar> t) {
super(t);
}
public void serialize(XMLGregorianCalendar value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
DateFormat dateFormatt = provider.getConfig().getDateFormat();
if(dateFormatt.getCalendar() == null) {
jgen.writeString(value.toString());
} else {
SimpleDateFormat dateFormat = (SimpleDateFormat)dateFormatt;
GregorianCalendar a = value.toGregorianCalendar();
Date date = value.toGregorianCalendar().getTime();
dateFormat.setTimeZone(TimeZone.getTimeZone(value.getTimeZone(value.getTimezone()).getDisplayName()));
jgen.writeString(dateFormat.format(date));
}
}
}
and the module class would be like:
public class XMLCalendarModule extends SimpleModule {
private static final String NAME = "CustomXMLCalendarModule";
private static final VersionUtil VERSION_UTIL = new VersionUtil() {
};
public XMLCalendarModule() {
super("CustomXMLCalendarModule", VERSION_UTIL.version());
this.addSerializer(XMLGregorianCalendar.class, new XMLCalendarSerializer());
}
}
and you can simply register this module like:
xmlMapper.registerModule(new XMLCalendarModule());
Upvotes: 2