即时与 ZoneDateTime。转换到另一个时区
Instant vs ZoneDateTime. Converting to another timezone
我很难理解 java.time 在 ZoneDateTime - Instant - LocalDateTime[ 之间=34=]
,到目前为止,我唯一知道的是:
- 即时工作介于两者之间
- Instant(在我的理解中),是一个时间戳(UTC),一个与人类时间流有关的时间戳,但没有时区
- 时区日期时间有时区
- Instant 没有时区,但可以在提供时区信息的情况下处理它
- LocalDate时间没有时区,不能处理时区,它是一个Date Time,与整个时间流(全球)的延续没有任何关系。
所以我有下面这个转换
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 然后再进行转换?
提前致谢
你的大部分子弹都是完全正确的。正如您在第一个项目符号中所说,只是您不应该使用 Instant
在 LocalDateTime
和 ZonedDateTime
之间工作。 Instant
和 LocalDateTime
之间的转换需要时区(或至少与 UTC 的偏移量),因此应该通过 ZonedDateTime
。所以 ZonedDateTime
是在其他两个之间使用的那个。正如我所说,其余的都是正确的。
您不是很清楚您对代码的期望,也不是更具体地观察到的结果有何不同。假设您希望在整个过程中使用相同的时间点,那么这一行就是您出乎意料的地方:
val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)
now
是您所在时区的 ZonedDateTime
(准确地说是 JVM 的默认时区)。通过仅从中获取日期和时间并将它们与不同的时区组合,您可以保持一天中的时间,但这样(可能)会改变时间流中的点。接下来,您要转换为 UTC 以保持时间点(即时),从而(可能)更改一天中的时间,也可能更改日期。从作为起点的 ZonedDateTime
开始,您已经一无所获,而且我看不出该操作有意义。要将 now
转换为 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
我用了 format
的 uuuu-MM-dd HH:mm:ss xxx zzzz
。
另外,我更愿意使用 withZoneSameInstant()
进行其他转换。那么我们就不需要经过一个Instant
.
val convertedInstant = now.withZoneSameInstant(zoneId)
它给出的结果与您的代码相同。
每个 类 讨论内容的简短概述:
Class
Date and time of day
Point in time
Time zone
ZonedDateTime
Yes
Yes
Yes
Instant
-
Yes
-
LocalDateTime
Yes
-
-
基本上 LocalDateTime
对您的目的没有任何用处,而且 Instant
虽然可用,但不是必需的。 ZonedDateTime
一个人就能满足你的需求。
我很难理解 java.time 在 ZoneDateTime - Instant - LocalDateTime[ 之间=34=] ,到目前为止,我唯一知道的是:
- 即时工作介于两者之间
- Instant(在我的理解中),是一个时间戳(UTC),一个与人类时间流有关的时间戳,但没有时区
- 时区日期时间有时区
- Instant 没有时区,但可以在提供时区信息的情况下处理它
- LocalDate时间没有时区,不能处理时区,它是一个Date Time,与整个时间流(全球)的延续没有任何关系。
所以我有下面这个转换
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 然后再进行转换?
提前致谢
你的大部分子弹都是完全正确的。正如您在第一个项目符号中所说,只是您不应该使用 Instant
在 LocalDateTime
和 ZonedDateTime
之间工作。 Instant
和 LocalDateTime
之间的转换需要时区(或至少与 UTC 的偏移量),因此应该通过 ZonedDateTime
。所以 ZonedDateTime
是在其他两个之间使用的那个。正如我所说,其余的都是正确的。
您不是很清楚您对代码的期望,也不是更具体地观察到的结果有何不同。假设您希望在整个过程中使用相同的时间点,那么这一行就是您出乎意料的地方:
val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)
now
是您所在时区的 ZonedDateTime
(准确地说是 JVM 的默认时区)。通过仅从中获取日期和时间并将它们与不同的时区组合,您可以保持一天中的时间,但这样(可能)会改变时间流中的点。接下来,您要转换为 UTC 以保持时间点(即时),从而(可能)更改一天中的时间,也可能更改日期。从作为起点的 ZonedDateTime
开始,您已经一无所获,而且我看不出该操作有意义。要将 now
转换为 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
我用了 format
的 uuuu-MM-dd HH:mm:ss xxx zzzz
。
另外,我更愿意使用 withZoneSameInstant()
进行其他转换。那么我们就不需要经过一个Instant
.
val convertedInstant = now.withZoneSameInstant(zoneId)
它给出的结果与您的代码相同。
每个 类 讨论内容的简短概述:
Class | Date and time of day | Point in time | Time zone |
---|---|---|---|
ZonedDateTime |
Yes | Yes | Yes |
Instant |
- | Yes | - |
LocalDateTime |
Yes | - | - |
基本上 LocalDateTime
对您的目的没有任何用处,而且 Instant
虽然可用,但不是必需的。 ZonedDateTime
一个人就能满足你的需求。