Skip to content

Commit

Permalink
Fix #308, Can't deserialize OffsetDateTime.MIN and `OffsetDateTime.…
Browse files Browse the repository at this point in the history
…MAX` (#325)
  • Loading branch information
JooHyukKim authored Nov 18, 2024
1 parent 3ed7e7e commit c860a7f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,25 @@ public class InstantDeserializer<T extends Temporal>
= JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS.enabledByDefault();

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

// @since 2.18.2
private static OffsetDateTime decimalToOffsetDateTime(FromDecimalArguments args) {
// [jackson-modules-java8#308] Since 2.18.2 : Fix can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
if (args.integer == OffsetDateTime.MIN.toEpochSecond() && args.fraction == OffsetDateTime.MIN.getNano()) {
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MIN.toEpochSecond(), OffsetDateTime.MIN.getNano()), OffsetDateTime.MIN.getOffset());
}
// [jackson-modules-java8#308] Since 2.18.2 : For OffsetDateTime.MAX case
if (args.integer == OffsetDateTime.MAX.toEpochSecond() && args.fraction == OffsetDateTime.MAX.getNano()) {
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(OffsetDateTime.MAX.toEpochSecond(), OffsetDateTime.MAX.getNano()), OffsetDateTime.MAX.getOffset());
}
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(args.integer, args.fraction), args.zoneId);
}

public static final InstantDeserializer<Instant> INSTANT = new InstantDeserializer<>(
Instant.class, DateTimeFormatter.ISO_INSTANT,
Instant::from,
Expand All @@ -82,7 +95,7 @@ public class InstantDeserializer<T extends Temporal>
OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
OffsetDateTime::from,
a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
InstantDeserializer::decimalToOffsetDateTime,
(d, z) -> (d.isEqual(OffsetDateTime.MIN) || d.isEqual(OffsetDateTime.MAX) ? d : d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()))),
true, // yes, replace zero offset with Z
DEFAULT_NORMALIZE_ZONE_ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,22 @@ public void testDeserializationNoAdjustIfMAX() throws Exception
assertEquals(date.getOffset(),actualValue.getOffset());
}

// [jackson-modules-java8#308] Can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
@Test
public void testOffsetDateTimeMinOrMax() throws Exception
{
_testOffsetDateTimeMinOrMax(OffsetDateTime.MIN);
_testOffsetDateTimeMinOrMax(OffsetDateTime.MAX);
}

private void _testOffsetDateTimeMinOrMax(OffsetDateTime offsetDateTime)
throws Exception
{
String ser = MAPPER.writeValueAsString(offsetDateTime);
OffsetDateTime result = MAPPER.readValue(ser, OffsetDateTime.class);
assertIsEqual(offsetDateTime, result);
}

private static void assertIsEqual(OffsetDateTime expected, OffsetDateTime actual)
{
assertTrue("The value is not correct. Expected timezone-adjusted <" + expected + ">, actual <" + actual + ">.",
Expand Down
4 changes: 4 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,7 @@ Emanuel Trandafir (@etrandafir93)
Ólafur Bragason (@olibraga)
* Reported #319: `java.time.DateTimeException` serialization fails
(2.18.1)

Joo Hyuk Kim (@JooHyukKim)
* Fixed #308: Can't deserialize `OffsetDateTime.MIN`: Invalid value for EpochDay
(2.18.2)
6 changes: 6 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ Modules:
=== Releases ===
------------------------------------------------------------------------

2.18.2 (not yet released)

#308: Can't deserialize `OffsetDateTime.MIN`: Invalid value for EpochDay
(reported by @sszuev)
(fix by Joo-Hyuk K)
2.18.1 (28-Oct-2024)
#319: `java.time.DateTimeException` serialization fails
Expand Down

0 comments on commit c860a7f

Please sign in to comment.