Skip to content
This repository was archived by the owner on Nov 7, 2019. It is now read-only.

Commit e9c6de6

Browse files
committed
Merge branch '2.6'
Conflicts: release-notes/CREDITS
2 parents 3a7976a + 79a7250 commit e9c6de6

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

release-notes/CREDITS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ Peter Royal (osi@github)
5252
* Reported #50: `Instant` schema representation is incorrect for timestamps serialization
5353
(2.6.4)
5454

55+
Krešimir Nesek (knes1@github)
56+
* Reported, contributed for #69: Serialization of Instant seems to throw exceptions
57+
when @JsonFormat is used
58+
(2.6.6)
59+
5560
Devin Smith (devinrsmith@github)
5661
* Reported #63: Should not leak `DateTimeException`s to caller
5762
(2.7.3)

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ No changes since 2.7.1
3333
#16: Instant is serialized as String by some dataformats/libs but can't be
3434
deserialized (unless manually converted to float)
3535
(reported by Andreas L)
36+
#69: Serialization of Instant seems to throw exceptions when when @JsonFormat is used
37+
(reported and fixed by Krešimir N)
3638

3739
2.6.5 (19-Jan-2016)
3840

src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/JSR310DateTimeDeserializerBase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.datatype.jsr310.deser;
22

3+
import java.time.ZoneId;
34
import java.time.format.DateTimeFormatter;
45
import java.util.Locale;
56

@@ -42,6 +43,11 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
4243
} else {
4344
df = DateTimeFormatter.ofPattern(pattern, locale);
4445
}
46+
//Issue #69: For instant serializers/deserializers we need to configure the formatter with
47+
//a time zone picked up from JsonFormat annotation, otherwise serialization might not work
48+
if (format.hasTimeZone()) {
49+
df = df.withZone(format.getTimeZone().toZoneId());
50+
}
4551
return withDateFormat(df);
4652
}
4753
// any use for TimeZone?

src/main/java/com/fasterxml/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ public JsonSerializer<?> createContextual(SerializerProvider prov,
111111
} else {
112112
dtf = DateTimeFormatter.ofPattern(pattern, locale);
113113
}
114+
//Issue #69: For instant serializers/deserializers we need to configure the formatter with
115+
//a time zone picked up from JsonFormat annotation, otherwise serialization might not work
116+
if (format.hasTimeZone()) {
117+
dtf = dtf.withZone(format.getTimeZone().toZoneId());
118+
}
114119
}
115120
if (useTimestamp != _useTimestamp || dtf != _formatter) {
116121
return withFormat(useTimestamp, dtf);

src/test/java/com/fasterxml/jackson/datatype/jsr310/TestInstantSerialization.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import static org.junit.Assert.assertTrue;
2222

2323
import java.time.Instant;
24+
import java.time.ZoneId;
25+
import java.time.ZonedDateTime;
2426
import java.time.format.DateTimeFormatter;
2527
import java.time.temporal.ChronoUnit;
2628
import java.time.temporal.Temporal;
@@ -33,6 +35,7 @@
3335
public class TestInstantSerialization extends ModuleTestBase
3436
{
3537
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_INSTANT;
38+
private static final String CUSTOM_PATTERN = "yyyy-MM-dd HH:mm:ss";
3639

3740
private final ObjectMapper mapper = newMapper();
3841

@@ -44,12 +47,29 @@ final static class Wrapper {
4447
* representation here
4548
*/
4649
//pattern="YYYY-mm-dd",
47-
shape=JsonFormat.Shape.STRING)
50+
shape=JsonFormat.Shape.STRING
51+
)
4852
public Instant value;
4953

5054
public Wrapper() { }
5155
public Wrapper(Instant v) { value = v; }
5256
}
57+
58+
final static class WrapperWithCustomPattern {
59+
@JsonFormat(
60+
pattern = CUSTOM_PATTERN,
61+
shape=JsonFormat.Shape.STRING,
62+
timezone = "UTC"
63+
)
64+
public Instant valueInUTC;
65+
66+
public WrapperWithCustomPattern() { }
67+
public WrapperWithCustomPattern(Instant v) {
68+
valueInUTC = v;
69+
}
70+
}
71+
72+
5373

5474
@Test
5575
public void testSerializationAsTimestamp01Nanoseconds() throws Exception
@@ -357,7 +377,7 @@ public void testDeserializationWithTypeInfo04() throws Exception
357377
}
358378

359379
@Test
360-
public void testCustomPatternWithAnnotations() throws Exception
380+
public void testCustomPatternWithAnnotations01() throws Exception
361381
{
362382
final Wrapper input = new Wrapper(Instant.ofEpochMilli(0));
363383
String json = mapper.writeValueAsString(input);
@@ -367,6 +387,25 @@ public void testCustomPatternWithAnnotations() throws Exception
367387
assertEquals(input.value, result.value);
368388
}
369389

390+
// [datatype-jsr310#69]
391+
@Test
392+
public void testCustomPatternWithAnnotations02() throws Exception
393+
{
394+
//Test date is pushed one year after start of the epoch just to avoid possible issues with UTC-X TZs which could
395+
//push the instant before tha start of the epoch
396+
final Instant instant = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0), ZoneId.of("UTC")).plusYears(1).toInstant();
397+
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CUSTOM_PATTERN);
398+
final String valueInUTC = formatter.withZone(ZoneId.of("UTC")).format(instant);
399+
400+
final WrapperWithCustomPattern input = new WrapperWithCustomPattern(instant);
401+
String json = mapper.writeValueAsString(input);
402+
403+
assertTrue("Instant in UTC timezone was not serialized as expected.", json.contains(aposToQuotes("'valueInUTC':'" + valueInUTC + "'")));
404+
405+
WrapperWithCustomPattern result = mapper.readValue(json, WrapperWithCustomPattern.class);
406+
assertEquals("Instant in UTC timezone was not deserialized as expected.", input.valueInUTC, result.valueInUTC);
407+
}
408+
370409
// [datatype-jsr310#16]
371410
@Test
372411
public void testDeserializationFromStringAsNumber() throws Exception

0 commit comments

Comments
 (0)