Skip to content

Commit

Permalink
Fix #166: deserialize OffsetDateTime.MIN or OffsetDateTime.MAX with A…
Browse files Browse the repository at this point in the history
…DJUST_DATES_TO_CONTEXT_TIME_ZONE enabled (#176)

* Do not adjust Time Zone if value is OffsetDateTime.MIN or OffsetDateTime.MAX with ADJUST_DATES_TO_CONTEXT_TIME_ZONE enabled.

* deleted private e-mail

* Fixing e-mail.
  • Loading branch information
kupci authored Jun 10, 2020
1 parent 0e6702c commit 67e06ee
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
2 changes: 1 addition & 1 deletion datetime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ more ambiguous integer types are read as fractional seconds without a decimal po

For TimeZone handling, `ADJUST_DATES_TO_CONTEXT_TIME_ZONE` (default: true) specifies whether the context provided by `java.time.TimeZone`
'SerializedProvider#getTimeZone()' should be used to adjust Date/Time values on deserialization, even if the value itself
contains timezone information. If disabled, it will only be used if the value itself does not contain any TimeZone information.
contains timezone information. If the value is `OffsetDateTime.MIN` or `OffsetDateTime.MAX`, the Date/Time value will not be adjusted. If disabled, it will only be used if the value itself does not contain any TimeZone information.

Finally, there are two features that apply to array handling. `UNWRAP_SINGLE_VALUE_ARRAYS` (default: false) allows auto-conversion from single-element arrays to non-JSON-array
values. If the JSON value contains more than one element in the array, deserialization will still fail. `ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT` (default: false) determines whether empty Array value ("[ ]" in JSON) is accepted
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class InstantDeserializer<T extends Temporal>
OffsetDateTime::from,
a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
(d, z) -> d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime())),
(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
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,45 @@ public void testStrictDeserializeFromEmptyString() throws Exception {
objectReader.readValue(valueFromEmptyStr);
}

// [module-java8#166]
@Test
public void testDeserializationNoAdjustIfMIN() throws Exception
{
OffsetDateTime date = OffsetDateTime.MIN;
ObjectMapper m = newMapper()
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, true)
.setTimeZone(TimeZone.getTimeZone(Z1))
.addMixIn(Temporal.class, MockObjectConfiguration.class);
Temporal value = m.readValue(
"[\"" + OffsetDateTime.class.getName() + "\",\"" + FORMATTER.format(date) + "\"]", Temporal.class
);

assertNotNull("The value should not be null.", value);
assertTrue("The value should be an OffsetDateTime.", value instanceof OffsetDateTime);
OffsetDateTime actualValue = (OffsetDateTime) value;
assertIsEqual(date, actualValue);
assertEquals(date.getOffset(),actualValue.getOffset());
}

@Test
public void testDeserializationNoAdjustIfMAX() throws Exception
{
OffsetDateTime date = OffsetDateTime.MAX;
ObjectMapper m = newMapper()
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, true)
.setTimeZone(TimeZone.getTimeZone(Z1))
.addMixIn(Temporal.class, MockObjectConfiguration.class);
Temporal value = m.readValue(
"[\"" + OffsetDateTime.class.getName() + "\",\"" + FORMATTER.format(date) + "\"]", Temporal.class
);

assertNotNull("The value should not be null.", value);
assertTrue("The value should be an OffsetDateTime.", value instanceof OffsetDateTime);
OffsetDateTime actualValue = (OffsetDateTime) value;
assertIsEqual(date, actualValue);
assertEquals(date.getOffset(),actualValue.getOffset());
}

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 @@ -103,3 +103,7 @@ Arturas Gusevas (agusevas@github)
Samantha Williamson (samwill@github)
* Contributed fix to #148: Allow strict `LocalDate` parsing
(2.11.0)

Moritz Orth ([email protected])
* Reported and suggested fix for #166: Cannot deserialize OffsetDateTime.MIN and
OffsetDateTime.MAX with ADJUST_DATES_TO_CONTEXT_TIME_ZONE enabled (2.12)

0 comments on commit 67e06ee

Please sign in to comment.