@@ -55,10 +55,23 @@ public class InstantDeserializer<T extends Temporal>
5555 = JavaTimeFeature .ALWAYS_ALLOW_STRINGIFIED_DATE_TIMESTAMPS .enabledByDefault ();
5656
5757 /**
58- * Constants used to check if ISO 8601 time string is colonless . See [jackson-modules-java8#131]
58+ * Constants used to check if ISO 8601 time string is colon-less . See [jackson-modules-java8#131]
5959 */
6060 protected static final Pattern ISO8601_COLONLESS_OFFSET_REGEX = Pattern .compile ("[+-][0-9]{4}(?=\\ [|$)" );
6161
62+ // @since 2.18.2
63+ private static OffsetDateTime decimalToOffsetDateTime (FromDecimalArguments args ) {
64+ // [jackson-modules-java8#308] Since 2.18.2 : Fix can't deserialize OffsetDateTime.MIN: Invalid value for EpochDay
65+ if (args .integer == OffsetDateTime .MIN .toEpochSecond () && args .fraction == OffsetDateTime .MIN .getNano ()) {
66+ return OffsetDateTime .ofInstant (Instant .ofEpochSecond (OffsetDateTime .MIN .toEpochSecond (), OffsetDateTime .MIN .getNano ()), OffsetDateTime .MIN .getOffset ());
67+ }
68+ // [jackson-modules-java8#308] Since 2.18.2 : For OffsetDateTime.MAX case
69+ if (args .integer == OffsetDateTime .MAX .toEpochSecond () && args .fraction == OffsetDateTime .MAX .getNano ()) {
70+ return OffsetDateTime .ofInstant (Instant .ofEpochSecond (OffsetDateTime .MAX .toEpochSecond (), OffsetDateTime .MAX .getNano ()), OffsetDateTime .MAX .getOffset ());
71+ }
72+ return OffsetDateTime .ofInstant (Instant .ofEpochSecond (args .integer , args .fraction ), args .zoneId );
73+ }
74+
6275 public static final InstantDeserializer <Instant > INSTANT = new InstantDeserializer <>(
6376 Instant .class , DateTimeFormatter .ISO_INSTANT ,
6477 Instant ::from ,
@@ -74,7 +87,7 @@ public class InstantDeserializer<T extends Temporal>
7487 OffsetDateTime .class , DateTimeFormatter .ISO_OFFSET_DATE_TIME ,
7588 OffsetDateTime ::from ,
7689 a -> OffsetDateTime .ofInstant (Instant .ofEpochMilli (a .value ), a .zoneId ),
77- a -> OffsetDateTime . ofInstant ( Instant . ofEpochSecond ( a . integer , a . fraction ), a . zoneId ) ,
90+ InstantDeserializer :: decimalToOffsetDateTime ,
7891 (d , z ) -> (d .isEqual (OffsetDateTime .MIN ) || d .isEqual (OffsetDateTime .MAX ) ? d : d .withOffsetSameInstant (z .getRules ().getOffset (d .toLocalDateTime ()))),
7992 true , // yes, replace zero offset with Z
8093 DEFAULT_NORMALIZE_ZONE_ID ,
0 commit comments