用不同的可能格式解析日期
Parsing date with differents possible format
我必须将 String
解析为 UTC 时间戳。 String
可以有那些格式:
YYYY-MM-DDThh:mm:ss.sssZ
YYYY-MM-DDThh:mm:ss.sss+/-hh:mm
YYYY-MM-DDThh:mm:ss.sss
(以UTC为准,所以在末尾加一个Z
)
执行此操作并避免的最佳方法是什么:
try {
firstDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
} catch (DateTimeParseException e) {
try {
secondDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
} catch (DateTimeParseException e2) {
thirdDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
}
}
有多种选择。这是一个简单的:
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS[XXX]")
.withZone(ZoneOffset.UTC);
public static Instant parse(String offsetDateTimeString) {
return OffsetDateTime.parse(offsetDateTimeString, formatter).toInstant();
}
让我们试试看:
System.out.println(parse("2018-08-04T21:41:55.987Z"));
System.out.println(parse("2018-08-04T19:41:55.987-02:00"));
System.out.println(parse("2018-08-04T21:41:55.987"));
这会打印:
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
格式模式字符串中的方括号包围了一个可选部分,因此偏移量可能存在也可能不存在。偏移量 X
使用 Z
作为偏移量零,因此与三种格式中的前两种匹配。要指定在字符串中没有偏移量时使用的偏移量,我在格式化程序上设置了默认的 UTC 时区。
变化包括:
- 您可以使用预定义的 ISO 格式,而不是自己编写整个格式模式字符串。
- 由于我们是在偏移量而不是时区之后,因此指定默认偏移量而不是默认时区可能更正确。
DateTimeFormatterBuilder
允许我们两者兼顾。所以这里有一个不同的格式化程序,您可以在上面的代码中使用:
private static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX]")
.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds())
.toFormatter();
结果相同。
我必须将 String
解析为 UTC 时间戳。 String
可以有那些格式:
YYYY-MM-DDThh:mm:ss.sssZ
YYYY-MM-DDThh:mm:ss.sss+/-hh:mm
YYYY-MM-DDThh:mm:ss.sss
(以UTC为准,所以在末尾加一个Z
)
执行此操作并避免的最佳方法是什么:
try {
firstDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
} catch (DateTimeParseException e) {
try {
secondDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
} catch (DateTimeParseException e2) {
thirdDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
}
}
有多种选择。这是一个简单的:
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS[XXX]")
.withZone(ZoneOffset.UTC);
public static Instant parse(String offsetDateTimeString) {
return OffsetDateTime.parse(offsetDateTimeString, formatter).toInstant();
}
让我们试试看:
System.out.println(parse("2018-08-04T21:41:55.987Z"));
System.out.println(parse("2018-08-04T19:41:55.987-02:00"));
System.out.println(parse("2018-08-04T21:41:55.987"));
这会打印:
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
格式模式字符串中的方括号包围了一个可选部分,因此偏移量可能存在也可能不存在。偏移量 X
使用 Z
作为偏移量零,因此与三种格式中的前两种匹配。要指定在字符串中没有偏移量时使用的偏移量,我在格式化程序上设置了默认的 UTC 时区。
变化包括:
- 您可以使用预定义的 ISO 格式,而不是自己编写整个格式模式字符串。
- 由于我们是在偏移量而不是时区之后,因此指定默认偏移量而不是默认时区可能更正确。
DateTimeFormatterBuilder
允许我们两者兼顾。所以这里有一个不同的格式化程序,您可以在上面的代码中使用:
private static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX]")
.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds())
.toFormatter();
结果相同。