Java 在时区将 ZonedDateTime 转换为 LocalDateTime

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49853999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 03:09:24  来源:igfitidea点击:

Convert ZonedDateTime to LocalDateTime at time zone

javajava-8timezonedatetime-conversionzoneddatetime

提问by Vitalii

I have an object of ZonedDateTimethat is constructed like this

我有一个ZonedDateTime像这样构造的对象

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

How can I convert it to LocalDateTimeat time zone of Switzerland? Expected result should be 16 april 2018 13:30.

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

采纳答案by Jon Skeet

How can I convert it to LocalDateTime at time zone of Switzerland?

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

You can convert the UTC ZonedDateTimeinto a ZonedDateTimewith the time zone of Switzerland, but maintaining the same instant in time, and then get the LocalDateTimeout of that, if you need to. I'd be tempted to keep it as a ZonedDateTimeunless you need it as a LocalDateTimefor some other reason though.

您可以将 UTCZonedDateTime转换为ZonedDateTime具有瑞士时区的 UTC ,但在时间上保持相同的时刻,然后在需要时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();

回答by Ravindra Ranwala

Try this out. Substitute US/Central with your timezone.

试试这个。用您的时区替换美国/中部。

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

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

回答by Stevers

It helps to understand the difference between LocalDateTime and ZonedDateTime. What you really want is a ZonedDateTime. If you wanted to remove the timezone from the string representation, you would convert it to a LocalDateTime.

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

What you're looking for is: ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of("Europe/Zurich"));

你要找的是: ZonedDateTime swissZonedDateTime = withZoneSameInstant(ZoneId.of("Europe/Zurich"));

LocalDateTime-this is basically a glorified string representation of a Date and Time; it is timezone agnostic, which means it does not represent any point in time on a timeline

LocalDateTime- 这基本上是日期和时间的美化字符串表示;它是时区不可知的,这意味着它不代表时间线上的任何时间点

Instant- this is a millisecond representation of time that has elapsed since EPOCH. This represents a specific instant in time on a timeline

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

ZonedDateTime- this also represents an instant in time on a timeline, but it represents it as a Date and Time with a TimeZone.

ZonedDateTime- 这也表示时间线上的一个瞬间,但它表示为带有 TimeZone 的日期和时间。

The code below illustrates how to use all 3.

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

If you were to compared the Instant values of both ZonedDateTimes from above, they would be equivalent because they both point to the same instant in time. Somewhere in Greenwich (UTC time zone) it is noon on October 25th; at the same time, in New York it would be 8am (America/NewYork time zone).

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

回答by Jon Nichols

Another option that seems a little more intuitive is to convert the zoned date to an instant, then use LocalDateTime.ofInstant:

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

I prefer this to withZoneSameInstantbecause that solution little more opaque - you're getting a ZonedDateTime that has to be in a particular internal state (the correct time zone). Using ofInstantcan be used on any ZonedDateTime in any time zone.

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