如何最小化此处将日期字符串转换为 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.time
、modern 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
适用于 Instant
或 OffsetDateTime
。您对 LocalDateTime
的使用特别向我表明您需要日期 and/or 时间,而不仅仅是时间时刻。如果是这样,请选择 OffsetDateTime
.
protected final OffsetDateTime dateTimeOfLoss
= OffsetDateTime.parse("2021-04-14T20:51:21.527Z");
那么 LocalDateTime
和 ZonedDateTime
应该没有什么用处。如果您仍然需要其中之一,也许对于您无法更改的 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 偏移量,这些信息您不能在这里有意义地使用。
正在将此字符串 "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.time
、modern 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
适用于 Instant
或 OffsetDateTime
。您对 LocalDateTime
的使用特别向我表明您需要日期 and/or 时间,而不仅仅是时间时刻。如果是这样,请选择 OffsetDateTime
.
protected final OffsetDateTime dateTimeOfLoss
= OffsetDateTime.parse("2021-04-14T20:51:21.527Z");
那么 LocalDateTime
和 ZonedDateTime
应该没有什么用处。如果您仍然需要其中之一,也许对于您无法更改的 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 偏移量,这些信息您不能在这里有意义地使用。