[2.12.0-rc1] Can no longer serialize using different timezones on independent OffsetDateTime fields
See original GitHub issueHi it would seem like #185 (PR for #175) removes the possibility of producing different offset formats with the same ObjectMapper.
In the example below you will see 3 cases:
- One using an ObjectMapper without setting it’s time zone.
- One using an ObjectMapper with it’s time zone set to the value appropriate for the the
offset
field. - One using an ObjectMapper with it’s time zone set to the value appropriate for the the
offset2
field.
None of these options seem to work. I think it might just be necessary to honor the given object’s timezone when the timezone of the ObjectMapper is not set, I would love to hear your opinion on this or if there’s an alternate way to make this work I would also love to hear about it.
I’ve added a fourth test case which shows that deserialization is possible when using DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE
. This makes me think that at a higher level the change introduces asymmetry in the behavior, and I think being able to go back and forth preserving the data is important.
Please let me know if I can improve this report or assist in any way.
import static org.junit.Assert.assertEquals;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonCreator.Mode;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.*;
import java.util.TimeZone;
import org.junit.Test;
public class ObjectMapperTest {
private static final LocalDateTime LOCAL = LocalDateTime.of(2018, 11, 26, 17, 53, 22);
private static final OffsetDateTime OFFSET = OffsetDateTime.of(LOCAL.plusSeconds(1), ZoneOffset.of("-05:00"));
private static final OffsetDateTime OFFSET_2 = OffsetDateTime.of(LOCAL.plusSeconds(3), ZoneOffset.of("Z"));
private static final TestPojo TEST_POJO = new TestPojo(OFFSET, OFFSET_2);
private static final String EXPECTED_JSON = "{"
+ "\"offset\":\"2018-11-26T17:53:23-05:00\","
+ "\"offset2\":\"11/26/2018 17:53:25Z\""
+ "}";
@Test
public void testSerialization() throws Exception {
ObjectMapper subject = newObjectMapper();
String json = subject.writeValueAsString(TEST_POJO);
assertEquals("Json should include timezone", EXPECTED_JSON, json);
}
@Test
public void testSerializationWithUTCTimezoneInMapper() throws Exception {
ObjectMapper subject = newObjectMapper();
subject.setTimeZone(TimeZone.getTimeZone(ZoneId.of("UTC")));
String json = subject.writeValueAsString(TEST_POJO);
assertEquals("Json should include timezone", EXPECTED_JSON, json);
}
@Test
public void testSerializationWithMinus5TimezoneInMapper() throws Exception {
ObjectMapper subject = newObjectMapper();
subject.setTimeZone(TimeZone.getTimeZone(ZoneId.of("-05:00")));
String json = subject.writeValueAsString(TEST_POJO);
assertEquals("Json should include timezone", EXPECTED_JSON, json);
}
@Test
public void testDeserialization() throws Exception {
ObjectMapper subject = newObjectMapper();
subject.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
String json = ("{"
+ " 'offset': '2018-11-26T17:53:23-05:00',"
+ " 'offset2': '11/26/2018 17:53:25Z'"
+ "}").replaceAll("'", "\"");
TestPojo pojo = subject.readValue(json, TestPojo.class);
assertEquals("The time is equivalent for offset", OFFSET, pojo.getOffset());
assertEquals("The time is equivalent for offset2", OFFSET_2, pojo.getOffset2());
}
private ObjectMapper newObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return mapper;
}
@JsonPropertyOrder({"offset", "offset2"})
static class TestPojo {
private static final String UTC_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
private static final String ANOTHER_DATETIME_FORMAT = "MM/dd/yyyy' 'HH:mm:ssXXX";
private final OffsetDateTime offset;
private final OffsetDateTime offset2;
@JsonCreator(mode = Mode.PROPERTIES)
public TestPojo(
@JsonProperty("offset") @JsonFormat(shape = JsonFormat.Shape.STRING,
pattern = UTC_DATETIME_FORMAT) OffsetDateTime offset,
@JsonProperty("offset2") @JsonFormat(shape = JsonFormat.Shape.STRING,
pattern = ANOTHER_DATETIME_FORMAT) OffsetDateTime offset2) {
this.offset = offset;
this.offset2 = offset2;
}
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = UTC_DATETIME_FORMAT)
public OffsetDateTime getOffset() { return offset; }
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = ANOTHER_DATETIME_FORMAT)
public OffsetDateTime getOffset2() { return offset2; }
}
}
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (7 by maintainers)
I added
MapperConfig.hasExplicitTimeZone()
(base class ofSerializationConfig
andDeserializationConfig
), so this is now accessible for 2.12.@cowtowncoder Thanks, I created a new issue at https://github.com/FasterXML/jackson-modules-java8/issues/228