This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details

Debug note

Ask questions

In the application I’m developing, I need to convert java.time.instantobject to java.sql.Timestamp.

When I create an Instant object:

Instant now = Instant.now();

I received something similar 2017-03-13T14:28:59.970z.

When I try to create a Timestamp object like this:

Timestamp current = Timestamp.from(now);

I received something similar 2017-03-13T16:28:59.970z. Same result, but with a 2 hour delay.

Can someone explain why this is happening and provide me with an answer to this problem without delay?

When I create like this:

LocalDateTime ldt = LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC);
Timestamp current = Timestamp.valueOf(ldt);
Copy the code

Everything is normal. But I try to avoid switching. Is there a way to just use Instant objects?

answer

I experimented by changing the computer’s time zone to Europe/Bucharest. This is UTC + 2 hours (same as your time zone).

Now, when I copy your code, I get results similar to yours:

   Instant now = Instant.now();
    System.out.println(now); / / prints the 2017-03-14 T06: roar. 621 z
    Timestamp current = Timestamp.from(now);
    System.out.println(current); / / the 08:16:32 2017-03-14. 621
Copy the code

The output is given in comment form. But I continue:

DateFormat df = DateFormat.getDateTimeInstance();
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    // the following prints: Timestamp in UTC: 14-03-2017 06:16:32
    System.out.println("Timestamp in UTC: " + df.format(current));
Copy the code

Now you can see that Timestamp is really consistent with Instant from scratch

(Only milliseconds don’t print, but I’m sure they’re there too).

You’ll do everything correctly and just get confused because at print time we implicitly call its toString method, which in turn gets the computer’s time zone Settings and displays the time in that time zone.

Because of this alone, the display is different.

Another thing you tried to use LocalDateTime seemed to work, but didn’t actually give you what you wanted:

 LocalDateTime ldt = LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC);
    System.out.println(ldt); / / the 2017-03-14 T06: roar. 819
    current = Timestamp.valueOf(ldt);
    System.out.println(current); / / the 06:16:32 2017-03-14. 819
    System.out.println("Timestamp in UTC: " + df.format(current)); / / the 14-03-2017 04:16:32
Copy the code

Now, when we Timestamp using our UTC print DateFormat, we can see that we are now 2 hours ahead of GMT 06:16:32, Instant is 04:16:32 UTC. Thus, the method is deceptive and looks like it’s working, but it’s not.

This shows the trouble that led to Java 8’s date and time classes being designed to replace older ones.

Therefore, the really effective solution to your problem might be to get yourself a JDBC 4.2 driver that can easily accept Instant objects, thus avoiding a full conversion of Timestamp to a JDBC 4.2 driver.

I don’t know if it’s available now, but I’m sure it will be.

The article translated from Stack Overflow: stackoverflow.com/questions/4…