diff --git a/datetime/src/main/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializer.java b/datetime/src/main/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializer.java index 4a599941..c046aaf1 100644 --- a/datetime/src/main/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializer.java +++ b/datetime/src/main/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializer.java @@ -2,7 +2,6 @@ import java.time.DateTimeException; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import tools.jackson.core.JacksonException; import tools.jackson.databind.DeserializationContext; @@ -11,7 +10,7 @@ public class ZonedDateTimeKeyDeserializer extends Jsr310KeyDeserializer { public static final ZonedDateTimeKeyDeserializer INSTANCE = new ZonedDateTimeKeyDeserializer(); - private ZonedDateTimeKeyDeserializer() { + protected ZonedDateTimeKeyDeserializer() { // singleton } @@ -19,9 +18,9 @@ private ZonedDateTimeKeyDeserializer() { protected ZonedDateTime deserialize(String key, DeserializationContext ctxt) throws JacksonException { - // not serializing timezone data yet try { - return ZonedDateTime.parse(key, DateTimeFormatter.ISO_OFFSET_DATE_TIME); + // Not supplying a formatter allows the use of all supported formats + return ZonedDateTime.parse(key); } catch (DateTimeException e) { return _handleDateTimeException(ctxt, ZonedDateTime.class, e, key); } diff --git a/datetime/src/test/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializerTest.java b/datetime/src/test/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializerTest.java new file mode 100644 index 00000000..416ffd54 --- /dev/null +++ b/datetime/src/test/java/tools/jackson/datatype/jsr310/deser/key/ZonedDateTimeKeyDeserializerTest.java @@ -0,0 +1,72 @@ +package tools.jackson.datatype.jsr310.deser.key; + +import org.junit.Test; + +import tools.jackson.core.type.TypeReference; + +import tools.jackson.databind.ObjectMapper; +import tools.jackson.datatype.jsr310.ModuleTestBase; + +import java.time.ZonedDateTime; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.*; + +// for [modules-java8#306] +public class ZonedDateTimeKeyDeserializerTest + extends ModuleTestBase +{ + private final ObjectMapper MAPPER = newMapper(); + private final TypeReference> MAP_TYPE_REF + = new TypeReference>() {}; + + @Test + public void Instant_style_can_be_deserialized() throws Exception { + Map map = MAPPER.readValue(getMap("2015-07-24T12:23:34.184Z"), + MAP_TYPE_REF); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals("2015-07-24T12:23:34.184Z", entry.getKey().toString()); + } + + @Test + public void ZonedDateTime_with_zone_name_can_be_deserialized() throws Exception { + Map map = MAPPER.readValue(getMap("2015-07-24T12:23:34.184Z[UTC]"), + MAP_TYPE_REF); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals("2015-07-24T12:23:34.184Z[UTC]", entry.getKey().toString()); + } + + @Test + public void ZonedDateTime_with_place_name_can_be_deserialized() throws Exception { + assumeFalse(System.getProperty("java.version").startsWith("1.8")); + + Map map = MAPPER.readValue(getMap("2015-07-24T12:23:34.184Z[Europe/London]"), + MAP_TYPE_REF); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals("2015-07-24T13:23:34.184+01:00[Europe/London]", entry.getKey().toString()); + } + + @Test + public void ZonedDateTime_with_place_name_can_be_deserialized_Java_8() throws Exception { + // Java 8 parses this format incorrectly due to https://bugs.openjdk.org/browse/JDK-8066982 + assumeTrue(System.getProperty("java.version").startsWith("1.8")); + + Map map = MAPPER.readValue(getMap("2015-07-24T12:23:34.184Z[Europe/London]"), + MAP_TYPE_REF); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals("2015-07-24T12:23:34.184+01:00[Europe/London]", entry.getKey().toString()); + } + + @Test + public void ZonedDateTime_with_offset_can_be_deserialized() throws Exception { + Map map = MAPPER.readValue(getMap("2015-07-24T12:23:34.184+02:00"), + MAP_TYPE_REF); + Map.Entry entry = map.entrySet().iterator().next(); + assertEquals("2015-07-24T12:23:34.184+02:00", entry.getKey().toString()); + } + + private static String getMap(String input) { + return "{\"" + input + "\": \"This is a string\"}"; + } +} diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 5ee2de10..bfad40fc 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,6 +8,15 @@ Modules: === Releases === ------------------------------------------------------------------------ +2.18.0 (not yet released) + +No changes since 2.17 + +2.17.1 (not yet released) + +#306: Only `DateTimeFormatter.ISO_OFFSET_DATE_TIME` accepted by `ZonedDateTimeKeyDeserializer` + (fix contributed by @caluml) + 2.17.0 (12-Mar-2024) #274: Deserializing `java.time.Month` from an int causes an off-by-one