Skip to content

Commit 0b66fde

Browse files
committed
...
1 parent 3ed7e7e commit 0b66fde

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

datetime/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ public class InstantDeserializer<T extends Temporal>
6767
*/
6868
protected static final Pattern ISO8601_COLONLESS_OFFSET_REGEX = Pattern.compile("[+-][0-9]{4}(?=\\[|$)");
6969

70+
/**
71+
*
72+
* @param args
73+
* @return
74+
*/
75+
private static OffsetDateTime decimalToOffsetDateTime(FromDecimalArguments args) {
76+
// [jackson-modules-java8#308] Fix can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
77+
if (args.integer == OffsetDateTime.MIN.toEpochSecond() && args.fraction == OffsetDateTime.MIN.getNano()) {
78+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MIN.toEpochSecond(), OffsetDateTime.MIN.getNano()), OffsetDateTime.MIN.getOffset());
79+
}
80+
// [jackson-modules-java8#308] For OffsetDateTime.MAX case
81+
if (args.integer == OffsetDateTime.MAX.toEpochSecond() && args.fraction == OffsetDateTime.MAX.getNano()) {
82+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MAX.toEpochSecond(), OffsetDateTime.MAX.getNano()), OffsetDateTime.MAX.getOffset());
83+
}
84+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(args.integer, args.fraction), args.zoneId);
85+
}
86+
87+
7088
public static final InstantDeserializer<Instant> INSTANT = new InstantDeserializer<>(
7189
Instant.class, DateTimeFormatter.ISO_INSTANT,
7290
Instant::from,
@@ -82,7 +100,7 @@ public class InstantDeserializer<T extends Temporal>
82100
OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
83101
OffsetDateTime::from,
84102
a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
85-
a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
103+
InstantDeserializer::decimalToOffsetDateTime,
86104
(d, z) -> (d.isEqual(OffsetDateTime.MIN) || d.isEqual(OffsetDateTime.MAX) ? d : d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()))),
87105
true, // yes, replace zero offset with Z
88106
DEFAULT_NORMALIZE_ZONE_ID,
@@ -542,5 +560,16 @@ public static class FromDecimalArguments // since 2.8.3
542560
this.fraction = fraction;
543561
this.zoneId = zoneId;
544562
}
563+
564+
public static boolean matches(FromDecimalArguments a, FromDecimalArguments b) {
565+
if (a == b) {
566+
return true;
567+
}
568+
if (a == null || b == null) {
569+
return false;
570+
}
571+
return a.integer == b.integer && a.fraction == b.fraction
572+
&& a.zoneId.equals(b.zoneId);
573+
}
545574
}
546575
}

datetime/src/test/java/com/fasterxml/jackson/datatype/jsr310/deser/OffsetDateTimeDeserTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import com.fasterxml.jackson.annotation.JsonFormat;
1212
import com.fasterxml.jackson.annotation.JsonFormat.Feature;
13+
import com.fasterxml.jackson.core.JsonProcessingException;
1314
import com.fasterxml.jackson.core.type.TypeReference;
1415
import com.fasterxml.jackson.databind.DeserializationFeature;
1516
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -803,6 +804,24 @@ public void testDeserializationNoAdjustIfMAX() throws Exception
803804
assertEquals(date.getOffset(),actualValue.getOffset());
804805
}
805806

807+
// [jackson-modules-java8#308] Can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
808+
@Test
809+
public void testOffsetDateTimeMinOrMax()
810+
throws Exception
811+
{
812+
_testOffsetDateTimeMinOrMax(OffsetDateTime.MIN);
813+
_testOffsetDateTimeMinOrMax(OffsetDateTime.MAX);
814+
}
815+
816+
private void _testOffsetDateTimeMinOrMax(OffsetDateTime offsetDateTime)
817+
throws Exception
818+
{
819+
ObjectMapper mapper = newMapper();
820+
String ser = mapper.writeValueAsString(offsetDateTime);
821+
OffsetDateTime result = mapper.readValue(ser, OffsetDateTime.class);
822+
assertIsEqual(offsetDateTime, result);
823+
}
824+
806825
private static void assertIsEqual(OffsetDateTime expected, OffsetDateTime actual)
807826
{
808827
assertTrue("The value is not correct. Expected timezone-adjusted <" + expected + ">, actual <" + actual + ">.",

0 commit comments

Comments
 (0)