Skip to content

Fixes 128: SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS for ZonedDateTime #141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}