在时区将 ZonedDateTime 转换为 LocalDateTime
Convert ZonedDateTime to LocalDateTime at time zone
我有一个 ZonedDateTime
的对象是这样构造的
ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
如何将其转换为瑞士时区的LocalDateTime
?预期结果应为 16 april 2018 13:30
.
试试这个。用您的时区替换 US/Central。
ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
System.out.println(z.withZoneSameInstant(ZoneId.of("US/Central")));
How can I convert it to LocalDateTime at time zone of Switzerland?
您可以将 UTC ZonedDateTime
转换为带有瑞士时区的 ZonedDateTime
,但保持同一时刻,然后从中获取 LocalDateTime
,如果你需要。我很想将它保留为 ZonedDateTime
,除非你出于其他原因需要它作为 LocalDateTime
。
ZonedDateTime utcZoned = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId swissZone = ZoneId.of("Europe/Zurich");
ZonedDateTime swissZoned = utcZoned.withZoneSameInstant(swissZone);
LocalDateTime swissLocal = swissZoned.toLocalDateTime();
有助于理解 LocalDateTime 和 ZonedDateTime 之间的区别。你真正想要的是 ZonedDateTime
。如果您想从字符串表示中删除时区,您可以将其转换为 LocalDateTime
.
您要找的是:
ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of("Europe/Zurich"));
LocalDateTime - 这基本上是 Date
和 Time
的美化字符串表示;它与时区无关,这意味着它不代表时间轴上的任何时间点
Instant - 这是自 EPOCH 以来经过的时间的毫秒表示。这表示时间轴上的特定时刻
ZonedDateTime - 这也表示时间轴上的一个瞬间,但是 它表示为 Date
和Time
与 TimeZone
.
下面的代码说明了如何使用所有 3。
LocalDateTime localDateTime = LocalDateTime.of(2018, 10, 25, 12, 00, 00); //October 25th at 12:00pm
ZonedDateTime zonedDateTimeInUTC = localDateTime.atZone(ZoneId.of("UTC"));
ZonedDateTime zonedDateTimeInEST = zonedDateTimeInUTC.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(localDateTime.toString()); // 018-10-25T12:00
System.out.println(zonedDateTimeInUTC.toString()); // 2018-10-25T12:00Z[UTC]
System.out.println(zonedDateTimeInEST.toString()); // 2018-10-25T08:00-04:00[America/New_York]
如果您要比较上面两个 ZonedDateTimes
的 Instant
值,它们将是等效的,因为它们都指向同一时刻。在格林威治某地(UTC 时区),10 月 25 日正午;同时,在纽约,时间是上午 8 点(America/NewYork 时区)。
另一个似乎更直观的选项是将分区日期转换为即时日期,然后使用 LocalDateTime.ofInstant:
ZonedDateTime zdt = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId zId = ZoneId.of("US/Central");
LocalDateTime l = LocalDateTime.ofInstant(zdt.toInstant(), zId);
与 withZoneSameInstant
相比,我更喜欢这个,因为该解决方案更加不透明 - 您将获得必须处于特定内部状态(正确的时区)的 ZonedDateTime。使用 ofInstant
可以在任何时区的任何 ZonedDateTime 上使用。
有很多方法可以实现您想要的。其中一些如下:
- 将给定的
ZonedDateTime
转换为 Instant
并从 Instant
导出 LocalDateTime
。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
Instant instant = zdtUtc.toInstant();
LocalDateTime ldtSwitzerland = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Zurich"));
- 使用
ZonedDateTime#withZoneSameInstant
将给定的ZonedDateTime
转换为所需时区的ZonedDateTime
,然后从ZonedDateTime
得到LocalDateTime
。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZonedDateTime zdtSwitzerland = zdtUtc.withZoneSameInstant(ZoneId.of("Europe/Zurich"));
LocalDateTime ldtSwitzerland = zdtSwitzerland.toLocalDateTime();
- 将给定的
ZonedDateTime
转换为 Instant
,后者可以使用 Instant#atZone
转换为 ZonedDateTime
,然后从 ZonedDateTime
.
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
Instant instant = zdtUtc.toInstant();
ZonedDateTime zdtSwitzerland = instant.atZone(ZoneId.of("Europe/Zurich"));
LocalDateTime ldtSwitzerland = zdtSwitzerland.toLocalDateTime();
- 使用
DateTimeFormatter
将给定的ZonedDateTime
格式化为与所需时区相关的日期时间字符串,然后通过解析获得的日期时间字符串派生LocalDateTime
。 注意:此方法仅供您学习使用;您应该在生产代码中实现第一种方式(最顶层)。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
DateTimeFormatter dtfSwitzerland = DateTimeFormatter.ISO_ZONED_DATE_TIME.withZone(ZoneId.of("Europe/Zurich"));
String strZdtSwitzerland = dtfSwitzerland.format(zdtUtc);
LocalDateTime ldt = LocalDateTime
.from(DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(strZdtSwitzerland, new ParsePosition(0)));
了解有关现代日期时间 API 的更多信息
我有一个 ZonedDateTime
的对象是这样构造的
ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
如何将其转换为瑞士时区的LocalDateTime
?预期结果应为 16 april 2018 13:30
.
试试这个。用您的时区替换 US/Central。
ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
System.out.println(z.withZoneSameInstant(ZoneId.of("US/Central")));
How can I convert it to LocalDateTime at time zone of Switzerland?
您可以将 UTC ZonedDateTime
转换为带有瑞士时区的 ZonedDateTime
,但保持同一时刻,然后从中获取 LocalDateTime
,如果你需要。我很想将它保留为 ZonedDateTime
,除非你出于其他原因需要它作为 LocalDateTime
。
ZonedDateTime utcZoned = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId swissZone = ZoneId.of("Europe/Zurich");
ZonedDateTime swissZoned = utcZoned.withZoneSameInstant(swissZone);
LocalDateTime swissLocal = swissZoned.toLocalDateTime();
有助于理解 LocalDateTime 和 ZonedDateTime 之间的区别。你真正想要的是 ZonedDateTime
。如果您想从字符串表示中删除时区,您可以将其转换为 LocalDateTime
.
您要找的是:
ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of("Europe/Zurich"));
LocalDateTime - 这基本上是 Date
和 Time
的美化字符串表示;它与时区无关,这意味着它不代表时间轴上的任何时间点
Instant - 这是自 EPOCH 以来经过的时间的毫秒表示。这表示时间轴上的特定时刻
ZonedDateTime - 这也表示时间轴上的一个瞬间,但是 它表示为 Date
和Time
与 TimeZone
.
下面的代码说明了如何使用所有 3。
LocalDateTime localDateTime = LocalDateTime.of(2018, 10, 25, 12, 00, 00); //October 25th at 12:00pm
ZonedDateTime zonedDateTimeInUTC = localDateTime.atZone(ZoneId.of("UTC"));
ZonedDateTime zonedDateTimeInEST = zonedDateTimeInUTC.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(localDateTime.toString()); // 018-10-25T12:00
System.out.println(zonedDateTimeInUTC.toString()); // 2018-10-25T12:00Z[UTC]
System.out.println(zonedDateTimeInEST.toString()); // 2018-10-25T08:00-04:00[America/New_York]
如果您要比较上面两个 ZonedDateTimes
的 Instant
值,它们将是等效的,因为它们都指向同一时刻。在格林威治某地(UTC 时区),10 月 25 日正午;同时,在纽约,时间是上午 8 点(America/NewYork 时区)。
另一个似乎更直观的选项是将分区日期转换为即时日期,然后使用 LocalDateTime.ofInstant:
ZonedDateTime zdt = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId zId = ZoneId.of("US/Central");
LocalDateTime l = LocalDateTime.ofInstant(zdt.toInstant(), zId);
与 withZoneSameInstant
相比,我更喜欢这个,因为该解决方案更加不透明 - 您将获得必须处于特定内部状态(正确的时区)的 ZonedDateTime。使用 ofInstant
可以在任何时区的任何 ZonedDateTime 上使用。
有很多方法可以实现您想要的。其中一些如下:
- 将给定的
ZonedDateTime
转换为Instant
并从Instant
导出LocalDateTime
。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
Instant instant = zdtUtc.toInstant();
LocalDateTime ldtSwitzerland = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Zurich"));
- 使用
ZonedDateTime#withZoneSameInstant
将给定的ZonedDateTime
转换为所需时区的ZonedDateTime
,然后从ZonedDateTime
得到LocalDateTime
。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZonedDateTime zdtSwitzerland = zdtUtc.withZoneSameInstant(ZoneId.of("Europe/Zurich"));
LocalDateTime ldtSwitzerland = zdtSwitzerland.toLocalDateTime();
- 将给定的
ZonedDateTime
转换为Instant
,后者可以使用Instant#atZone
转换为ZonedDateTime
,然后从ZonedDateTime
.
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
Instant instant = zdtUtc.toInstant();
ZonedDateTime zdtSwitzerland = instant.atZone(ZoneId.of("Europe/Zurich"));
LocalDateTime ldtSwitzerland = zdtSwitzerland.toLocalDateTime();
- 使用
DateTimeFormatter
将给定的ZonedDateTime
格式化为与所需时区相关的日期时间字符串,然后通过解析获得的日期时间字符串派生LocalDateTime
。 注意:此方法仅供您学习使用;您应该在生产代码中实现第一种方式(最顶层)。
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
DateTimeFormatter dtfSwitzerland = DateTimeFormatter.ISO_ZONED_DATE_TIME.withZone(ZoneId.of("Europe/Zurich"));
String strZdtSwitzerland = dtfSwitzerland.format(zdtUtc);
LocalDateTime ldt = LocalDateTime
.from(DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(strZdtSwitzerland, new ParsePosition(0)));
了解有关现代日期时间 API 的更多信息