【问题标题】:LocalDateTime at zone doesn’t display the zone’s hour of day区域的 LocalDateTime 不显示该区域的一天中的小时
【发布时间】:2026-01-29 03:25:01
【问题描述】:

我在LocalDateTime lastUpdated 中有一个UTC 日期和时间。我想显示给定区域的时间和日期,但无论是哪个区域,我都会得到相同的时间。对于以下代码:

System.out.println(lastUpdated);
System.out.println(lastUpdated.atZone(ZoneId.of("Europe/Paris")));
System.out.println(lastUpdated.atZone(ZoneId.of("America/Los_Angeles")));

我得到:

2018-05-26T21:33:46
2018-05-26T21:33:46+02:00[Europe/Paris]
2018-05-26T21:33:46-07:00[America/Los_Angeles]

但我想得到的是:

2018-05-26T21:33:46
2018-05-26T**23**:33:46+02:00[Europe/Paris]
2018-05-26T**14**:33:46-07:00[America/Los_Angeles]

区域信息对我来说是可选的。我只需要在区域的适当时间。有没有办法实现?

【问题讨论】:

标签: java datetime java-time localdate


【解决方案1】:

您正在使用LocalDateTime,这是一个没有时区的日期和时间指示,就像您在与自己时区的人讨论日期和时间时一样。 atZone 返回那个日期的ZonedDateTime,就好像你在那个时区谈论它一样。

因此,为了获得不同的时间,您需要将 ZonedDateTime 转换为 Instant,这是为整个星球确定的时间点。然后可以将 Instant 再次转换为 ZonedDateTime

LocalDateTime lastUpdated = LocalDateTime.now();
ZonedDateTime zonedDateTime = lastUpdated.atZone(ZoneId.of("Europe/Paris"));
System.out.println(zonedDateTime);
ZonedDateTime other = ZonedDateTime.ofInstant(zonedDateTime.toInstant(), ZoneId.of("America/Los_Angeles"));
System.out.println(other);

输出:

2018-05-27T21:53:53.754+02:00[Europe/Paris]
2018-05-27T12:53:53.754-07:00[America/Los_Angeles]

【讨论】:

  • 感谢您的解释 :) 对掌握这个想法很有帮助。
【解决方案2】:

我的印象是,您将“无时区信息”与“UTC 时区...

错了。如果你不说时区是什么,那么你就没有关于时区的任何具体信息。

因此,您的 2018-05-26T21:33:46 不是日期和时间,UTC,而是该日期的日期和时间的概念,而不知道存在时区的概念。当你去问某人今天是几号,现在几点时,你会得到它。不,他们不会认为您可能还想考虑您当前所在的时区。这家伙根本不会认为有时区之类的东西,但他会能够知道现在是什么日子和时间。

因此,要将日期时间 UTC 转换为其他时区的日期时间,您可以这样做:

ZonedDateTime time = lastUpdated.atZone(ZoneId.of("UTC"));
System.out.println(time);
System.out.println(time.withZoneSameInstant​(ZoneId.of("Europe/Paris")));
System.out.println(time.withZoneSameInstant​(ZoneId.of("America/Los_Angeles")));

【讨论】:

  • 更好。没记住withZoneSameInstant
  • 正确答案。说“UTC LocalDateTime”是自相矛盾的。
  • 我明白了。感谢您的详细解释。我误解了这个概念。现在很清楚了:)
  • 我什至可以使用OffsetDateTime time = lastUpdated.atOffset(ZoneOffset.UTC);,然后使用time.atZoneSameInstant​(…)
  • @OleV.V.在语义级别上效果更好。但是当我开始认为一种或另一种方法并不重要时,我们就进入了这个领域。