You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
InstantDeserializer deserializes the nanosecond portion of fractional timestamps incorrectly: -1.000000001 deserializes to 1969-12-31T23:59:59.000000001Z instead of 1969-12-31T23:59:58.999999999Z#359
Open
Strongbeard opened this issue
Feb 17, 2025
· 0 comments
2.15.4 - 2.19 and the current master branch (commit c84b1a9 as of this post).
I have not tested anything earlier than what I plan to use.
Description
Please correct me if I am misguided on how negative fractional representations of timestamps should be parsed into java.time.Instant objects. I expected -1.000000001 to deserialize to 1969-12-31T23:59:58.999999999Z, but currently it deserializes to 1969-12-31T23:59:59.000000001Z.
I assume when "splitting" the fraction into its whole seconds and nanoseconds portions, the negative sign should be distributed to both. In other words: -1.000000001 == -1 + -0.000000001, but instead the behavior appears to be -1.000000001 == -1 + 0.000000001.
Strangely, any scenario where the seconds portion is 0 deserializes as I expect it to. For example, -0.000000001 deserializes to 1969-12-31T23:59:59.999999999Z. For some reason, the distribution of the negativity from seconds to nanoseconds is preserved here.
Adding the following unit test to datetime/src/test/java/tools/jackson/datatype/jsr310/deser/InstantDeserTest.java should demonstrate the issue, where test 4 fails and test 5 succeeds:
The following error is produced when executing the tests:
[ERROR] tools.jackson.datatype.jsr310.deser.InstantDeserTest.testDeserializationAsFloat04 -- Time elapsed: 0.128 s <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <1969-12-31T23:59:58.999999999Z> but was: <1969-12-31T23:59:59.000000001Z>
at [email protected]/org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at [email protected]/org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at [email protected]/org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
at [email protected]/org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
at [email protected]/org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
at [email protected]/org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1145)
at tools.jackson.datatype.javatime/tools.jackson.datatype.jsr310.deser.InstantDeserTest.testDeserializationAsFloat04(InstantDeserTest.java:121)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
If my assumptions are correct, then the fix appears more complicated than just changing the negativeAdjustment boolean passed to the call to DecimalUtils.extractSecondsAndNanos(BigDecimal, BiFunction, boolean) within the _fromDecimal(DeserializationContext, BigDecimal) function of InstantDeserializer to false since that causes unit test ZonedDateTimeSerTest#testSerializationAsTimestamp01NegativeSeconds to fail.
Related Issues
I believe this is related to the implementation of the fix for issues #304, #69, and #132.
The text was updated successfully, but these errors were encountered:
Version
2.15.4
-2.19
and the currentmaster
branch (commit c84b1a9 as of this post).I have not tested anything earlier than what I plan to use.
Description
Please correct me if I am misguided on how negative fractional representations of timestamps should be parsed into
java.time.Instant
objects. I expected-1.000000001
to deserialize to1969-12-31T23:59:58.999999999Z
, but currently it deserializes to1969-12-31T23:59:59.000000001Z
.I assume when "splitting" the fraction into its whole seconds and nanoseconds portions, the negative sign should be distributed to both. In other words:
-1.000000001 == -1 + -0.000000001
, but instead the behavior appears to be-1.000000001 == -1 + 0.000000001
.Strangely, any scenario where the seconds portion is
0
deserializes as I expect it to. For example,-0.000000001
deserializes to1969-12-31T23:59:59.999999999Z
. For some reason, the distribution of the negativity from seconds to nanoseconds is preserved here.Adding the following unit test to
datetime/src/test/java/tools/jackson/datatype/jsr310/deser/InstantDeserTest.java
should demonstrate the issue, where test 4 fails and test 5 succeeds:The following error is produced when executing the tests:
If my assumptions are correct, then the fix appears more complicated than just changing the
negativeAdjustment
boolean passed to the call toDecimalUtils.extractSecondsAndNanos(BigDecimal, BiFunction, boolean)
within the_fromDecimal(DeserializationContext, BigDecimal)
function ofInstantDeserializer
tofalse
since that causes unit testZonedDateTimeSerTest#testSerializationAsTimestamp01NegativeSeconds
to fail.Related Issues
I believe this is related to the implementation of the fix for issues #304, #69, and #132.
The text was updated successfully, but these errors were encountered: