如何将java.sql.Timestamp转换为UTC时间?

12
public static void main(String[] args) {

    LocalDateTime ldt = LocalDateTime.now();

    ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());

    Instant instant = Instant.from(zdt);

    Timestamp timestamp = Timestamp.from(instant);

    System.out.println(ldt + "\n");

    System.out.println(zdt + "\n");

    System.out.println(instant + "\n");

    System.out.println(timestamp + "\n");
}

然后它会打印出:

2017-05-07T18:13:26.969

2017-05-07T18:13:26.969-04:00[America/New_York]

2017-05-07T22:13:26.969Z

2017-05-07 18:13:26.969

如何使SQL TimestampInstant保存相同的时间?我需要能够从任何地方获取Timestamp并将其转换为当地的时间。问题在于,它始终保存为与我的系统时钟设置相同的时间。


当使用不存储时区的Oracle DATE列时,以下代码对我很有用。 Timestamp.valueOf(ZonedDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneOffset.UTC).toLocalDateTime()) - AlikElzin-kilaka
2个回答

19
你最好从一个LocalDateTime中获取一个Timestamp,而不是从一个Instant中获取。
第一步是将你的ZonedDateTime转换为GMT:
ZonedDateTime gmt = zdt.withZoneSameInstant(ZoneId.of("GMT"));

接着你可以通过 LocalDateTime 将其转换为 Timestamp

Timestamp timestamp = Timestamp.valueOf(gmt.toLocalDateTime());

这很有帮助。Instant非常具有欺骗性,因为它会打印当前的UTC时间,但是当转换为Timestamp时,会显示我的本地时间。因此,当它保存到远程数据库时,它将是我所在位置的任何时间。我知道Timestamp没有时区,而Instant是从一个纪元偏移量,但如果Timestamp记录的是本地时间而不是当前的UTC时间,那么它就完全没用了。这是一个很难提出的问题,因为每个人都自动假设我认为它应该显示一个时区。 - Skywarp
这似乎帮助我解决了时间戳本地时间转换问题。我不知道是否过度转换,但以下链将存储在UTC中的长整型通过LDT转换为时间戳,而不是从Instant转换:Timestamp.valueOf(LocalDateTime.ofEpochSecond(longEpochVal, 0, ZoneOffset.UTC)) - Robert Casey
值得注意的是 Timestamp 本身有点时区不可知的感觉..? 例如,如果您打印 Timestamp 的 fastTime,您会得到 UTC 中的毫秒数,但如果您使用 .toString,则是 toString 方法将其转换为 UTC+X... Instant.toString() 返回 UTC 时区的时间。另一方面,Timezone.toString() 返回本地机器时区的时间。请参见:https://www.baeldung.com/java-time-instant-to-java-sql-timestamp - niid
LocaleDateTime 丢弃与时区相关的任何信息。它将始终返回本地时区的值。zdt 将具有本地值而非 GMT。因此,添加任何区域偏移量进行转换都不会有任何变化。我尝试过这样做。 - Ayush Kumar
@Skywarp 我同意,Timestamp应该是区域特定的解释,但不包含区域信息,这很愚蠢。因此,它应该始终返回UTC。 - Splitframe

-1

如果你想要表示“带有时区的时间戳”的值,你可能需要使用setTimestamp的特定重载形式,该形式接受一个Calendar对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接