当前位置: 首页 > 知识库问答 >
问题:

Instant vs ZoneDateTime。转换到另一个时区

薄高懿
2023-03-14

我很难理解ZoneDateTime-Instant-LocalDateTime之间的java.time,到目前为止,我唯一知道的是:

  • Instant在两者之间工作
  • Instant(在我的理解中),是时间时刻(UTC)的时间印记,与人类时间流动相关的时间印记,但没有时区
  • 区域日期时间有时区
  • Instant没有时区,但可以在提供了时区信息的情况下处理它
  • LocalDate时间没有时区,不能处理区域,它是一个日期时间,与整个时间流(全局)的延续没有任何相关性。

下面是我的转换

val seoul = "Asia/Seoul"

val zoneId = ZoneId.of(seoul)
val now = ZonedDateTime.now()

val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)
val convertedInstant = now.toInstant().atZone(zoneId)

// expected output
println(convertedInstant.format(DateTimeFormatter.ofPattern(format)))

// not expected output
println(converted.format(DateTimeFormatter.ofPattern(format)))

输出

2021-05-02 03:15:13
2021-05-02 09:15:13

我正在尝试将给定的时间转换为另一个时区,这是一个用户移动到不同时区的用例,我需要更新有关存储日期的任何信息。

为什么我在第二个上得到一个不正确的值...?为什么我必须先将其转换为Instant并继续转换?

提前谢谢你

共有1个答案

苍元章
2023-03-14

你的大多数子弹都是完全正确的。只有您不应该像您在第一个项目符号中所说的那样,在本地日期时间和分区日期时间之间工作。在Instant(即时)和LocalDateTime(本地日期时间)之间转换需要一个时区(或至少与UTC的偏移量),因此应该经过ZonedDateTime(分区日期时间)。因此,ZonedDateTime是在其他两个时间段之间使用的时间段。正如我所说,其余的都是正确的。

您并不完全清楚您对代码的期望,也不清楚更具体地观察到的结果有何不同。假设您想始终使用相同的时间点,这一行就是您感到惊讶的地方:

val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)

现在是您自己时区中的分区DateTime(确切地说是JVM的默认时区)。通过仅从中提取日期和时间,并将它们与不同的时区相结合,可以保持一天中的时间,但这样(可能)会改变时间流中的时间点。接下来,您将转换为UTC,以保持时间点(即时),从而(可能)更改一天中的时间和日期。你的起点是ZonedDateTime,现在你什么都没有了,我看不出这个操作有什么意义。要将时间轴上的点立即转换为UTC,请使用更简单的:

val convertedZoneDateTIme = now.withZoneSameInstant(ZoneOffset.UTC)

通过此更改,您的两个输出在时间点上一致。示例输出:

2021-05-07 02:30:16 +09:00 Korean Standard Time
2021-05-06 17:30:16 +00:00 Z

我使用了uuu-MM-dd HH: mm: ss xxx zzzz格式

对于您的其他转换,我更喜欢使用with ZoneSameInstant()。然后我们不需要通过Instant

val convertedInstant = now.withZoneSameInstant(zoneId)

它会给出与您的代码相同的结果。

简要概述所讨论的每门课程的内容:

 类似资料:
  • 我期待但我得到的是作为。我错过了什么?

  • 这里是一个测试用例,它生成的一个结果是IST,另一个结果是GMT。我认为这两种情况下都应该只生成GMT。

  • 问题内容: 法国说如何将时区中的当前时间(日期时间)转换为另一个时区?我在SO中环顾四周,但没有找到任何可以帮助我的帖子。我正在使用SQL Server 2008。 问题答案: 在这里检查

  • 问题内容: 我正在寻找一种将一个时区的日期转换为另一个时区的函数。 它需要两个参数, 日期(格式为“ 2019/04/10 10:10:30 +0000”) 时区字符串(“亚洲/雅加达”) 是否有捷径可寻? 问题答案: var aestTime = new Date().toLocaleString(“en-US”, {timeZone: “Australia/Brisbane”});

  • 问题内容: 如何将这样的日期(在时区中)转换为时区?确保夏令时能正确处理? 问题答案: 使用和。

  • 问题内容: 我正在使用第三方存储系统,无论出于什么原因,无论输入什么内容,它都只会返回stdClass对象。因此,我很想知道是否有一种方法可以将stdClass对象转换/转换为给定类型的完整对象。 例如: 我只是将stdClass转换为数组并将其提供给BusinessClass构造函数,但是也许有一种方法可以还原我不知道的初始类。 注意:我对“更改存储系统”类型的答案不感兴趣,因为它不是关注点。请