Skip to content

Commit ed21550

Browse files
vetlercowtowncoder
authored andcommitted
Fix #127 - ZonedDateTime in map keys can now be serialized with zone IDs
1 parent 9532f8f commit ed21550

4 files changed

Lines changed: 71 additions & 7 deletions

File tree

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/key/ZonedDateTimeKeySerializer.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.core.JsonGenerator;
88
import com.fasterxml.jackson.core.JsonProcessingException;
99
import com.fasterxml.jackson.databind.JsonSerializer;
10+
import com.fasterxml.jackson.databind.SerializationFeature;
1011
import com.fasterxml.jackson.databind.SerializerProvider;
1112

1213
public class ZonedDateTimeKeySerializer extends JsonSerializer<ZonedDateTime> {
@@ -20,12 +21,14 @@ private ZonedDateTimeKeySerializer() {
2021
@Override
2122
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
2223
JsonProcessingException {
23-
/*
24-
* Serialization of timezone data is unwanted (not ISO). Offset is kept, timezone info is thrown away here.
25-
*
26-
* Keeping timezone info is a new feature which needs to be implemented.
24+
/* [modules-java8#127]: Serialization of timezone data is disabled by default, but can be
25+
* turned on by enabling `SerializationFeature.WRITE_DATES_WITH_ZONE_ID`
2726
*/
28-
gen.writeFieldName(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value));
27+
if (serializers.isEnabled(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)) {
28+
gen.writeFieldName(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(value));
29+
} else {
30+
gen.writeFieldName(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value));
31+
}
2932
}
3033

3134
}

datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/ser/WriteZoneIdTest.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
import java.time.Instant;
44
import java.time.ZoneId;
55
import java.time.ZonedDateTime;
6+
import java.util.HashMap;
67

78
import com.fasterxml.jackson.annotation.JsonFormat;
89
import com.fasterxml.jackson.databind.ObjectMapper;
10+
import com.fasterxml.jackson.databind.SerializationFeature;
11+
import com.fasterxml.jackson.databind.json.JsonMapper;
12+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
13+
import com.fasterxml.jackson.datatype.jsr310.MockObjectConfiguration;
914
import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase;
1015

1116
import org.junit.Assert;
1217
import org.junit.Test;
1318

19+
import static org.junit.Assert.assertEquals;
20+
1421
public class WriteZoneIdTest extends ModuleTestBase
1522
{
1623
static class DummyClassWithDate {
@@ -26,18 +33,47 @@ public DummyClassWithDate(ZonedDateTime date) {
2633
}
2734
}
2835

36+
private static ObjectMapper MAPPER = newMapper();
37+
38+
@Test
39+
public void testSerialization01() throws Exception
40+
{
41+
ZoneId id = ZoneId.of("America/Chicago");
42+
String value = MAPPER.writeValueAsString(id);
43+
assertEquals("The value is not correct.", "\"America/Chicago\"", value);
44+
}
45+
46+
@Test
47+
public void testSerialization02() throws Exception
48+
{
49+
ZoneId id = ZoneId.of("America/Anchorage");
50+
String value = MAPPER.writeValueAsString(id);
51+
assertEquals("The value is not correct.", "\"America/Anchorage\"", value);
52+
}
53+
54+
@Test
55+
public void testSerializationWithTypeInfo01() throws Exception
56+
{
57+
ZoneId id = ZoneId.of("America/Denver");
58+
ObjectMapper mapper = mapperBuilder()
59+
.addMixIn(ZoneId.class, MockObjectConfiguration.class)
60+
.addModule(new JavaTimeModule())
61+
.build();
62+
String value = mapper.writeValueAsString(id);
63+
assertEquals("The value is not correct.", "[\"java.time.ZoneRegion\",\"America/Denver\"]", value);
64+
}
65+
2966
@Test
3067
public void testJacksonAnnotatedPOJOWithDateWithTimezoneToJson() throws Exception
3168
{
32-
ObjectMapper mapper = newMapper();
3369
String ZONE_ID_STR = "Asia/Krasnoyarsk";
3470
final ZoneId ZONE_ID = ZoneId.of(ZONE_ID_STR);
3571

3672
DummyClassWithDate input = new DummyClassWithDate(ZonedDateTime.ofInstant(Instant.ofEpochSecond(0L), ZONE_ID));
3773

3874
// 30-Jun-2016, tatu: Exact time seems to vary a bit based on DST, so let's actually
3975
// just verify appending of timezone id itself:
40-
String json = mapper.writeValueAsString(input);
76+
String json = MAPPER.writeValueAsString(input);
4177
if (!json.contains("\"1970-01-01T")) {
4278
Assert.fail("Should contain time prefix, did not: "+json);
4379
}
@@ -46,4 +82,16 @@ public void testJacksonAnnotatedPOJOWithDateWithTimezoneToJson() throws Exceptio
4682
Assert.fail("Should contain zone id "+match+", does not: "+json);
4783
}
4884
}
85+
86+
@Test
87+
public void testMapSerialization() throws Exception {
88+
final ZonedDateTime datetime = ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Warsaw]");
89+
final HashMap<ZonedDateTime, String> map = new HashMap<>();
90+
map.put(datetime, "");
91+
92+
String json = MAPPER.writer()
93+
.with(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)
94+
.writeValueAsString(map);
95+
Assert.assertEquals("{\"2007-12-03T10:15:30+01:00[Europe/Warsaw]\":\"\"}", json);
96+
}
4997
}

release-notes/CREDITS-2.x

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,11 @@ Michael O'Keeffe (kupci@github)
7373
* Constributed fix for #114: Prevent deserialization of "" as `null` for `LocalDate`,
7474
`LocalDateTime` in "strict" (non-lenient) mode
7575
(2.10.0)
76+
77+
Michał Żmuda (zmumi@github)
78+
* Reported #127: ZonedDateTime in map keys ignores option to write Zone IDs
79+
(2.10.1)
80+
81+
Vetle Leinonen-Roeim (vetler@github)
82+
* Contributed fix for #127: ZonedDateTime in map keys ignores option to write Zone IDs
83+
(2.10.1)

release-notes/VERSION-2.x

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Modules:
88
=== Releases ===
99
------------------------------------------------------------------------
1010

11+
2.10.1 (not yet released)
12+
13+
#127: ZonedDateTime in map keys ignores option to write Zone IDs
14+
(reported by Michał Ż, fixed by Vetle L-R)
15+
1116
2.10.0 (26-Sep-2019)
1217

1318
#51: `YearKeyDeserializer` doesn't work with non-padded year values

0 commit comments

Comments
 (0)