如何最小化此处将日期字符串转换为 UTC 的代码

How to minimize the code here which converts date string into UTC

正在将此字符串 "2021-04-14T20:51:21.527Z" 转换为 UTC 值。

以下有效,但非常冗长...

protected final LocalDateTime dateTimeOfLoss = LocalDateTime.ofInstant(Instant.parse("2021-04-14T20:51:21.527Z"), ZoneId.of(ZoneOffset.UTC.getId()));
protected final ZonedDateTime zdt = dateTimeOfLoss.atZone(ZoneId.of(ZoneOffset.UTC.getId()));

我是为了可读性,这是为了测试。

假设您需要这两个字段,将它们翻转以首先构建 ZonedDateTime。然后,您无需再次指定区域即可获得 LocalDateTime

protected final ZonedDateTime zdt = Instant.parse("2021-04-14T20:51:21.527Z").atZone(ZoneOffset.UTC);
protected final LocalDateTime dateTimeOfLoss = zdt.toLocalDateTime();

只需解析为 Instant.

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.parse("2021-04-14T20:51:21.527Z");
        System.out.println(instant);

        // If you want to convert it to ZonedDateTime
        ZonedDateTime zdt = instant.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(zdt);

        // If you want to convert it to OffsetDateTime
        OffsetDateTime odt = instant.atOffset(ZoneOffset.UTC);
        System.out.println(odt);

        // If you want to convert it to LocalDate
        LocalDateTime ldt = zdt.toLocalDateTime(); // Alternatively, odt.toLocalDateTime();
        System.out.println(ldt);
    }
}

输出:

2021-04-14T20:51:21.527Z
2021-04-14T20:51:21.527Z[Etc/UTC]
2021-04-14T20:51:21.527Z
2021-04-14T20:51:21.527

Instant represents an instantaneous point on the timeline and the value you get on parsing is already in UTC. The Z in the output is the timezone designator 用于零时区偏移。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移量为 +00:00 小时)。

详细了解 java.timemodern date-time API* from Trail: Date Time


* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and

寻找 OffsetDateTime

您没有使用正确的类型。您的字符串值 2021-04-14T20:51:21.527Z 适用于 InstantOffsetDateTime。您对 LocalDateTime 的使用特别向我表明您需要日期 and/or 时间,而不仅仅是时间时刻。如果是这样,请选择 OffsetDateTime.

protected final OffsetDateTime dateTimeOfLoss
        = OffsetDateTime.parse("2021-04-14T20:51:21.527Z");

那么 LocalDateTimeZonedDateTime 应该没有什么用处。如果您仍然需要其中之一,也许对于您无法更改的 API,请编写一个转换方法:

protected LocalDateTime getDateTimeOfLossLdt() {
    return dateTimeOfLoss.toLocalDateTime();
}

protected ZonedDateTime getZdt() {
    return dateTimeOfLoss.atZoneSameInstant(dateTimeOfLoss.getOffset());
}

为什么?

LocalDateTime 不对: LocalDateTime 几乎没有什么好的用途。大多数情况下,日期和时间用于建立时间点,您的字符串通过包含尾随 Z 来实现这一点,它表示与 UTC 的偏移量为零。通过转换为 LocalDateTime,您将丢弃该偏移量,因此会丢失有关您拥有的时间的信息,并且在 return 中什么也得不到。 LocalDateTime 给你什么 OffsetDateTime 给不了你。

ZonedDateTime 不对: 如我所说,您的字符串包含 UTC 偏移量。它不包含时区。 Asia/Krasnoyarsk 和 America/Grand_Turk 是时区的例子。因此,虽然 ZonedDateTime 有效,但它确实没有动力。我认为它比您需要的更重量级,因为时区包括历史和已知的未来 UTC 偏移量,这些信息您不能在这里有意义地使用。