Skip to content

Commit

Permalink
Fixes 128: SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS for Zon…
Browse files Browse the repository at this point in the history
…edDateTime

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.
  • Loading branch information
vetler authored and cowtowncoder committed Oct 8, 2019
1 parent 9a4f38f commit de0b69c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.DecimalUtils;

public class ZonedDateTimeKeySerializer extends JsonSerializer<ZonedDateTime> {

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

@Override
public void serialize(ZonedDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
JsonProcessingException {
JsonProcessingException {
/* [modules-java8#127]: Serialization of timezone data is disabled by default, but can be
* turned on by enabling `SerializationFeature.WRITE_DATES_WITH_ZONE_ID`
*/
if (serializers.isEnabled(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)) {
gen.writeFieldName(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(value));
} else if (useTimestamps(serializers)) {
if (useNanos(serializers)) {
gen.writeFieldName(DecimalUtils.toBigDecimal(value.toEpochSecond(), value.getNano()).toString());
} else {
gen.writeFieldName(String.valueOf(value.toInstant().toEpochMilli()));
}
} else {
gen.writeFieldName(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value));
}
}

private static boolean useNanos(SerializerProvider serializers) {
return serializers.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
}

private static boolean useTimestamps(SerializerProvider serializers) {
return serializers.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.ModuleTestBase;

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

private static final ZonedDateTime DATE_TIME_1 = ZonedDateTime.of(
2015, 3, 14, 9, 26, 53, 590 * 1000 * 1000, ZoneOffset.UTC);
Expand Down Expand Up @@ -72,4 +74,21 @@ public void testDeserialization2() throws Exception {
Assert.assertEquals("Value is incorrect", asMap(DATE_TIME_2_OFFSET, "test"),
READER.readValue(mapAsString(DATE_TIME_2_STRING, "test")));
}

@Test
public void testSerializationToInstantWithNanos() throws Exception {
String value = newMapperBuilder().enable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS).build()
.writerFor(TYPE_REF).writeValueAsString(asMap(DATE_TIME_1, "test"));
Assert.assertEquals("Value is incorrect",
mapAsString(String.valueOf(DATE_TIME_1.toEpochSecond()) + '.' + DATE_TIME_1.getNano(), "test"), value);
}

@Test
public void testSerializationToInstantWithoutNanos() throws Exception {
String value = newMapperBuilder().enable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)
.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS).build()
.writerFor(TYPE_REF).writeValueAsString(asMap(DATE_TIME_1, "test"));
Assert.assertEquals("Value is incorrect",
mapAsString(String.valueOf(DATE_TIME_1.toInstant().toEpochMilli()), "test"), value);
}
}

0 comments on commit de0b69c

Please sign in to comment.