在时区将ZonedDateTime转换为LocalDateTime

时间:2018-04-16 09:33:29

标签: java java-8 timezone datetime-conversion zoneddatetime

我有ZonedDateTime的对象,就像这样构建

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

如何在瑞士时区将其转换为LocalDateTime?预期结果应为16 april 2018 13:30

5 个答案:

答案 0 :(得分:24)

  

如何在瑞士时区将其转换为LocalDateTime?

您可以将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();

答案 1 :(得分:3)

试一试。用您的时区替换US / Central。

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

System.out.println(z.withZoneSameInstant(ZoneId.of("US/Central")));

答案 2 :(得分:1)

它有助于了解LocalDateTime和ZonedDateTime之间的区别。您真正想要的是ZonedDateTime。如果要从字符串表示形式中删除时区,请将其转换为LocalDateTime。

您要寻找的是: ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of(“ Europe / Zurich”));

LocalDateTime -基本上是日期和时间的修饰字符串表示;它与时区无关,这意味着它不代表时间轴上的任何时间点

即时-这是自EPOCH以来经过的时间的毫秒数。这表示时间轴上的特定时间点

ZonedDateTime -这也代表时间轴上的即时时间,但它通过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值,它们将是等效的,因为它们都指向同一时间点。 10月25日中午,格林威治(UTC时区)某个地方。同时,在纽约时间是上午8点(美国/纽约时区)。

答案 3 :(得分:0)

似乎更直观的另一个选项是将分区日期转换为即时日期,然后使用LocalDateTime.ofInstant:

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
ZoneId z = ZoneId.of("US/Central");
LocalDateTime l = LocalDateTime.ofInstant(z.toInstant(), z);

我更喜欢withZoneSameInstant,因为该解决方案更加不透明-您得到的ZonedDateTime必须处于特定的内部状态(正确的时区)。使用ofInstant可以在任何时区的任何ZonedDateTime上使用。

答案 4 :(得分:0)

有很多方法可以实现您想要的。其中一些如下:

  1. 将给定的 ZonedDateTime 转换为 Instant 并从 LocalDateTime 导出 Instant
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

Instant instant = zdtUtc.toInstant();

LocalDateTime ldtSwitzerland = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Zurich"));

ONLINE DEMO

  1. 使用 ZonedDateTime#withZoneSameInstant 将给定的 ZonedDateTime 转换为所需时区中的 ZonedDateTime,然后从 LocalDateTime 中获取 ZonedDateTime
ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);

ZonedDateTime zdtSwitzerland = zdtUtc.withZoneSameInstant(ZoneId.of("Europe/Zurich"));

LocalDateTime ldtSwitzerland = zdtSwitzerland.toLocalDateTime();

ONLINE DEMO

  1. 将给定的 ZonedDateTime 转换为 Instant,后者可以使用 Instant#atZone 转换为 ZonedDateTime,然后从 {{1} 中获取 LocalDateTime }.
ZonedDateTime

ONLINE DEMO

  1. 使用 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

ONLINE DEMO

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。