将 java.time.Instant 转换为没有区域偏移量的 java.sql.Timestamp [英] Convert java.time.Instant to java.sql.Timestamp without Zone offset

查看:29
本文介绍了将 java.time.Instant 转换为没有区域偏移量的 java.sql.Timestamp的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在开发的应用程序中,我需要将java.time.Instant 对象转换为java.sql.Timestamp.当我创建 Instant 对象时:

In the application I am developing, I need to convert java.time.Instant object to java.sql.Timestamp. When I create Instant object like:

Instant now = Instant.now();

我收到类似 2017-03-13T14:28:59.970Z 的信息.当我尝试像这样创建 Timestamp 对象时:

I receive something like 2017-03-13T14:28:59.970Z. And when I try to create Timestamp object like this:

Timestamp current = Timestamp.from(now);

我收到类似 2017-03-13T16:28:59.970Z 的信息.相同的结果,但额外延迟了 2 小时.有人可以解释为什么会发生这种情况,并为我提供解决此问题的答案,而不会有这种延迟吗?

I receive something like 2017-03-13T16:28:59.970Z. The same result but with an additional 2 hour delay. Can someone explain why this is happening and provide me with an answer to fix this problem without this delay?

当我这样创建时:

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

一切正常,但我尽量避免转换.有没有办法只使用 Instant 对象来做到这一点?

Everything works well, but I try to avoid conversions. Is there a way to do this by only using Instant object?

推荐答案

为了进行实验,我将计算机的时区更改为欧洲/布加勒斯特.这是 UTC + 2 小时,如您所在的时区.

I changed my computer’s time zone to Europe/Bucharest for an experiment. This is UTC + 2 hours like your time zone.

现在,当我复制您的代码时,得到的结果与您类似:

Now when I copy your code I get a result similar to yours:

    Instant now = Instant.now();
    System.out.println(now); // prints 2017-03-14T06:16:32.621Z
    Timestamp current = Timestamp.from(now);
    System.out.println(current); // 2017-03-14 08:16:32.621

输出在注释中给出.但是,我继续:

Output is given in comments. However, I go on:

    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));

现在您可以看到 Timestamp 确实与我们开始的 Instant 一致(只有毫秒未打印,但我相信它们也在那里).所以你做的一切都是正确的,只是感到困惑,因为当我们打印 Timestamp 时,我们隐式地调用了它的 toString 方法,而这个方法反过来获取计算机的时区设置和显示该区域的时间.正因为如此,显示方式不同.

Now you can see that the Timestamp really agrees with the Instant we started out from (only the milliseconds are not printed, but I trust they are in there too). So you have done everything correctly and only got confused because when we printed the Timestamp we were implicitly calling its toString method, and this method in turn grabs the computer’s time zone setting and displays the time in this zone. Only because of this, the displays are different.

您尝试使用 LocalDateTime 的另一件事似乎有效,但它确实没有给您想要的:

The other thing you attempted, using LocalDateTime, appears to work, but it really does not give you what you want:

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

现在,当我们使用 UTC DateFormat 打印 Timestamp 时,我们可以看到它早了 2 小时,当 即时 是 06:16:32 UTC.所以这个方法是骗人的,看似有效,实则不然.

Now when we print the Timestamp using our UTC DateFormat, we can see that it is 2 hours too early, 04:16:32 UTC when the Instant is 06:16:32 UTC. So this method is deceiving, it looks like it’s working, but it doesn’t.

这显示了导致设计 Java 8 日期和时间类以替换旧的类的麻烦.因此,解决您的问题的真正和好的解决方案可能是为自己准备一个 JDBC 4.2 驱动程序,它可以很容易地接受 Instant 对象,这样您就可以避免完全转换为 Timestamp.我不知道这是否适合您,但我相信它会.

This shows the trouble that lead to the design of the Java 8 date and time classes to replace the old ones. So the real and good solution to your problem would probably be to get yourself a JDBC 4.2 driver that can accept an Instant object readily so you can avoid converting to Timestamp altogether. I don’t know if that’s available for you just yet, but I’m convinced it will be.

这篇关于将 java.time.Instant 转换为没有区域偏移量的 java.sql.Timestamp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆