Skip to content

Commit c860a7f

Browse files
authored
Fix #308, Can't deserialize OffsetDateTime.MIN and OffsetDateTime.MAX (#325)
1 parent 3ed7e7e commit c860a7f

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,25 @@ public class InstantDeserializer<T extends Temporal>
6161
= JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault();
6262

6363
/**
64-
* Constants used to check if ISO 8601 time string is colonless. See [jackson-modules-java8#131]
64+
* Constants used to check if ISO 8601 time string is colon-less. See [jackson-modules-java8#131]
6565
*
6666
* @since 2.13
6767
*/
6868
protected static final Pattern ISO8601_COLONLESS_OFFSET_REGEX = Pattern.compile("[+-][0-9]{4}(?=\\[|$)");
6969

70+
// @since 2.18.2
71+
private static OffsetDateTime decimalToOffsetDateTime(FromDecimalArguments args) {
72+
// [jackson-modules-java8#308] Since 2.18.2 : Fix can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
73+
if (args.integer == OffsetDateTime.MIN.toEpochSecond() && args.fraction == OffsetDateTime.MIN.getNano()) {
74+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MIN.toEpochSecond(), OffsetDateTime.MIN.getNano()), OffsetDateTime.MIN.getOffset());
75+
}
76+
// [jackson-modules-java8#308] Since 2.18.2 : For OffsetDateTime.MAX case
77+
if (args.integer == OffsetDateTime.MAX.toEpochSecond() && args.fraction == OffsetDateTime.MAX.getNano()) {
78+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MAX.toEpochSecond(), OffsetDateTime.MAX.getNano()), OffsetDateTime.MAX.getOffset());
79+
}
80+
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(args.integer, args.fraction), args.zoneId);
81+
}
82+
7083
public static final InstantDeserializer<Instant> INSTANT = new InstantDeserializer<>(
7184
Instant.class, DateTimeFormatter.ISO_INSTANT,
7285
Instant::from,
@@ -82,7 +95,7 @@ public class InstantDeserializer<T extends Temporal>
8295
OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
8396
OffsetDateTime::from,
8497
a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
85-
a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
98+
InstantDeserializer::decimalToOffsetDateTime,
8699
(d, z) -> (d.isEqual(OffsetDateTime.MIN) || d.isEqual(OffsetDateTime.MAX) ? d : d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()))),
87100
true, // yes, replace zero offset with Z
88101
DEFAULT_NORMALIZE_ZONE_ID,

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,22 @@ public void testDeserializationNoAdjustIfMAX() throws Exception
803803
assertEquals(date.getOffset(),actualValue.getOffset());
804804
}
805805

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

release-notes/CREDITS-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,7 @@ Emanuel Trandafir (@etrandafir93)
203203
Ólafur Bragason (@olibraga)
204204
* Reported #319: `java.time.DateTimeException` serialization fails
205205
(2.18.1)
206+
207+
Joo Hyuk Kim (@JooHyukKim)
208+
* Fixed #308: Can't deserialize `OffsetDateTime.MIN`: Invalid value for EpochDay
209+
(2.18.2)

release-notes/VERSION-2.x

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Modules:
88
=== Releases ===
99
------------------------------------------------------------------------
1010

11+
2.18.2 (not yet released)
12+
13+
#308: Can't deserialize `OffsetDateTime.MIN`: Invalid value for EpochDay
14+
(reported by @sszuev)
15+
(fix by Joo-Hyuk K)
16+
1117
2.18.1 (28-Oct-2024)
1218
1319
#319: `java.time.DateTimeException` serialization fails

0 commit comments

Comments
 (0)