Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instant prior to Instant.EPOCH is not equal after serialization/deserialization #120

Closed
naiello opened this issue Jul 15, 2019 · 3 comments
Milestone

Comments

@naiello
Copy link

naiello commented Jul 15, 2019

It seems that certain java.time.Instant instances prior to Instant.EPOCH are not equal after being serialized, then deserialized.

As you can see from this gist, serializing then deserializing an Instant one millisecond prior to the epoch (1969-12-31T23:59:59.999Z) results in an Instant 1.998 seconds earlier: 1969-12-31T23:59:58.001Z

As mentioned above, this affects only Instants with a nonzero nanos field. Instant.ofEpochMilli(-1001) is not equal after deserialization, while Instant.ofEpochMilli(1000) is equal.

Using OpenJDK8 1.8.0_202 and Jackson 2.9.8.

@cowtowncoder
Copy link
Member

From gist:

import java.io.IOException;
import java.time.Instant;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public final class JacksonInstantSerializationBug {
    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper()
                .registerModule(new JavaTimeModule());

        final Instant original = Instant.ofEpochMilli(-1);
        final String serialized = mapper.writeValueAsString(original);
        final Instant deserialized = mapper.readValue(serialized, Instant.class);

        System.out.println(String.format("Original:      secs=%s, nanos=%s",
                original.getEpochSecond(), original.getNano()));
        System.out.println(String.format("Serialized:    %s", serialized));
        System.out.println(String.format("Deserialized:  secs=%s, nanos=%s",
                deserialized.getEpochSecond(), deserialized.getNano()));
        System.out.println(deserialized.equals(original) ? "Equal!" : "Not equal!");

        /*
         *  stdout:
         *    Original:      secs=-1, nanos=999000000
         *    Serialized:    -1.999000000
         *    Deserialized:  secs=-2, nanos=1000000
         *    Not equal!
         *
         *  This holds for any instant prior to Instant.EPOCH with non-zero nanos;
         *  i.e. Instant.ofEpochMilli(-1234) is not equal after deserialization, but Instant.ofEpochMilli(-1000) is.
         *  
         *  Reproduced with Jackson-datatype-jsr310 version 2.9.8
         */
    }
}

@cowtowncoder
Copy link
Member

May be wrong but seems like this could be relatively easy to diagnose (figure out the underlying problem), even if solution was not easy. Hence tagging.

@cowtowncoder cowtowncoder added the good first issue Issue that seems easy to resolve and is likely a good candidate for contributors new to project label Aug 13, 2019
@kupci kupci mentioned this issue Aug 27, 2019
@cowtowncoder
Copy link
Member

Ok: as per comments, this is duplicate of #69, so will close in favor of it.

@cowtowncoder cowtowncoder added duplicate and removed good first issue Issue that seems easy to resolve and is likely a good candidate for contributors new to project labels Aug 30, 2019
@cowtowncoder cowtowncoder added this to the 2.10.0.pr2 milestone Aug 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants