你不应该想要 LocalDateTime
例如:两个字符串2019-12-03T10:00:01+09:00
和2019-12-03T10:00:01-08:00
表示相隔 17 小时的时间点,但将被解析为相等LocalDateTime
的对象。我不认为你想要那个。
也LocalDateTime
可能不适合订单结束时间。它不知道任何时区或与 UTC 的偏移量,因此每个人和看到它的每一段代码都可以自由地解释为他们碰巧想到的时区,而不是预期的时区。这留下了意外结果的巨大风险。对于 20 种用途中的至少 19 种,使用 a Instant
、 anOffsetDateTime
或 a会更好ZonedDateTime
。
解析有无偏移:定义一个默认时区
您需要接受没有偏移量的字符串。然后,您还需要知道为此类字符串假定哪个时区——默认时区。然后你也可以解析它们。
例如:
ZoneId defaultTimeZone = ZoneId.of("America/Guatemala");
ZoneId resultTimeZone = ZoneId.of("Europe/Rome");
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX]")
.toFormatter();
for (String input : new String[] {
"2019-12-03T10:00:01+01:00",
"2019-12-03T10:00:00-06:00",
"2019-12-03T10:00:00"
}) {
TemporalAccessor parsed = formatter.parseBest(input,
OffsetDateTime::from, LocalDateTime::from);
ZonedDateTime dateTime;
if (parsed instanceof OffsetDateTime) {
dateTime = ((OffsetDateTime) parsed).atZoneSameInstant(resultTimeZone);
} else {
dateTime = ((LocalDateTime) parsed).atZone(defaultTimeZone)
.withZoneSameInstant(resultTimeZone);
}
System.out.format("%-25s is parsed into %s%n", input, dateTime);
}
此片段的输出是:
2019-12-03T10:00:01+01:00 is parsed into 2019-12-03T10:00:01+01:00[Europe/Rome]
2019-12-03T10:00:00-06:00 is parsed into 2019-12-03T17:00+01:00[Europe/Rome]
2019-12-03T10:00:00 is parsed into 2019-12-03T17:00+01:00[Europe/Rome]
我[XXX]
在格式模式字符串中使用来表示可选的偏移量。如果可以的话,调用parseBest()
解析为一个OffsetDateTime
(偏移量存在),否则解析为LocalDateTime
我随后转换的一个。最后,我将所有解析的日期和时间转换为一个时区,以便用户可以看到一致的结果。