diff --git a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/key/ZonedDateTimeKeySerializer.java b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/key/ZonedDateTimeKeySerializer.java index dababc8c..66fef7f8 100644 --- a/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/key/ZonedDateTimeKeySerializer.java +++ b/datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/key/ZonedDateTimeKeySerializer.java @@ -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 { @@ -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); + } + } diff --git a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/ZonedDateTimeAsKeyTest.java b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/ZonedDateTimeAsKeyTest.java index a65d6b08..c0ed5954 100644 --- a/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/ZonedDateTimeAsKeyTest.java +++ b/datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/key/ZonedDateTimeAsKeyTest.java @@ -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; @@ -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); @@ -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); + } }