Skip to content

Commit de0b69c

Browse files
vetlercowtowncoder
authored andcommitted
Fixes 128: SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS for ZonedDateTime
This enables SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS for keys in maps that are ZonedDateTime. It also takes into account SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS.
1 parent 9a4f38f commit de0b69c

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

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

+16-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.databind.JsonSerializer;
1010
import com.fasterxml.jackson.databind.SerializationFeature;
1111
import com.fasterxml.jackson.databind.SerializerProvider;
12+
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;
1213

1314
public class ZonedDateTimeKeySerializer extends JsonSerializer<ZonedDateTime> {
1415

@@ -20,15 +21,29 @@ private ZonedDateTimeKeySerializer() {
2021

2122
@Override
2223
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
23-
JsonProcessingException {
24+
JsonProcessingException {
2425
/* [modules-java8#127]: Serialization of timezone data is disabled by default, but can be
2526
* turned on by enabling `SerializationFeature.WRITE_DATES_WITH_ZONE_ID`
2627
*/
2728
if (serializers.isEnabled(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)) {
2829
gen.writeFieldName(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(value));
30+
} else if (useTimestamps(serializers)) {
31+
if (useNanos(serializers)) {
32+
gen.writeFieldName(DecimalUtils.toBigDecimal(value.toEpochSecond(), value.getNano()).toString());
33+
} else {
34+
gen.writeFieldName(String.valueOf(value.toInstant().toEpochMilli()));
35+
}
2936
} else {
3037
gen.writeFieldName(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value));
3138
}
3239
}
3340

41+
private static boolean useNanos(SerializerProvider serializers) {
42+
return serializers.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
43+
}
44+
45+
private static boolean useTimestamps(SerializerProvider serializers) {
46+
return serializers.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
47+
}
48+
3449
}

datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/ZonedDateTimeAsKeyTest.java

+19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.core.type.TypeReference;
1010
import com.fasterxml.jackson.databind.ObjectMapper;
1111
import com.fasterxml.jackson.databind.ObjectReader;
12+
import com.fasterxml.jackson.databind.SerializationFeature;
1213
import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase;
1314

1415
import org.junit.Assert;
@@ -20,6 +21,7 @@ public class ZonedDateTimeAsKeyTest extends ModuleTestBase
2021
};
2122
private static final ZonedDateTime DATE_TIME_0 = ZonedDateTime.ofInstant(Instant.ofEpochSecond(0), ZoneOffset.UTC);
2223
private static final String DATE_TIME_0_STRING = "1970-01-01T00:00:00Z";
24+
private static final Instant DATE_TIME_0_INSTANT = DATE_TIME_0.toInstant();
2325

2426
private static final ZonedDateTime DATE_TIME_1 = ZonedDateTime.of(
2527
2015, 3, 14, 9, 26, 53, 590 * 1000 * 1000, ZoneOffset.UTC);
@@ -72,4 +74,21 @@ public void testDeserialization2() throws Exception {
7274
Assert.assertEquals("Value is incorrect", asMap(DATE_TIME_2_OFFSET, "test"),
7375
READER.readValue(mapAsString(DATE_TIME_2_STRING, "test")));
7476
}
77+
78+
@Test
79+
public void testSerializationToInstantWithNanos() throws Exception {
80+
String value = newMapperBuilder().enable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS).build()
81+
.writerFor(TYPE_REF).writeValueAsString(asMap(DATE_TIME_1, "test"));
82+
Assert.assertEquals("Value is incorrect",
83+
mapAsString(String.valueOf(DATE_TIME_1.toEpochSecond()) + '.' + DATE_TIME_1.getNano(), "test"), value);
84+
}
85+
86+
@Test
87+
public void testSerializationToInstantWithoutNanos() throws Exception {
88+
String value = newMapperBuilder().enable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)
89+
.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS).build()
90+
.writerFor(TYPE_REF).writeValueAsString(asMap(DATE_TIME_1, "test"));
91+
Assert.assertEquals("Value is incorrect",
92+
mapAsString(String.valueOf(DATE_TIME_1.toInstant().toEpochMilli()), "test"), value);
93+
}
7594
}

0 commit comments

Comments
 (0)