将时区日期时间转换为时区的本地日期时间



我有一个ZonedDateTime对象是这样构造

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

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

如何将其转换为瑞士时区的本地日期时间?

您可以将 UTCZonedDateTime转换为具有瑞士时区的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- 这基本上是DateTime的美化字符串表示;它与时区无关,这意味着它不代表时间轴上的任何时间点

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

ZonedDateTime- 这也表示时间轴上的一个时刻,但它表示为带有TimeZoneDateTime

下面的代码说明了如何使用所有 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()); // 2018-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]

如果要从上面比较两个ZonedDateTimesInstant值,它们将是等效的,因为它们都指向同一时刻。在格林威治(UTC时区)的某个地方,现在是10月25日中午;同时,在纽约,将是上午8点(美国/纽约时区)。

试试这个。将"美国/中部"替换为您的时区。

ZonedDateTime z = ZonedDateTime.of(LocalDate.now().atTime(11, 30), ZoneOffset.UTC);
System.out.println(z.withZoneSameInstant(ZoneId.of("US/Central")));

另一个看起来更直观的选项是将分区日期转换为即时日期,然后使用 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 上使用。

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

  1. 将给定的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"));

在线演示

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

在线演示

  1. >将给定的ZonedDateTime转换为可以使用Instant#atZone转换为ZonedDateTimeInstant,然后从ZonedDateTime中获取LocalDateTime
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();

在线演示

  1. 使用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 的更多信息,请参阅跟踪:日期时间

相关内容

  • 没有找到相关文章

最新更新