我有各种格式的时间戳,例如:
2018-07-21T00:50:39
2017-11-20T23:18:27.529Z
我需要将它们解析为 java.util.Date,并尝试了以下方法,它们都适用于第一种格式,但第二种格式失败。
以下是我尝试过的方法,但都是错误的:
1.
private Date try3(String dateString) {
return Date.from(Instant.parse(dateString).atZone(ZoneId.of("UTC")).toInstant());
}
第一次格式化失败,错误:
java.time.format.DateTimeParseException: Text '2017-11-20T23:18:28' could not be parsed at index 19
2.
private Date try2(String dateString) {
return Date.from(LocalDateTime.parse(dateString).atZone(ZoneId.of("UTC")).toInstant());
}
对于第二种格式,此方法抛出错误:
java.time.format.DateTimeParseException: Text '2017-11-20T23:18:27.529Z' could not be parsed, unparsed text found at index 23
3:
private Date try1(String dateString) {
return Date.from(ZonedDateTime.parse(dateString,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(ZoneId.of("UTC"))).toInstant());
}
对于第二种格式,上述方法会抛出错误:
java.time.format.DateTimeParseException: Text '2017-11-20T23:18:27.529Z' could not be parsed, unparsed text found at index 19
我最终得到了Joda 库:
private Date try4(String dateString) {
return new DateTime(dateString).withZone(DateTimeZone.UTC).toDate();
}
但是在 Java 时间库中真的有办法做到这一点吗?
最佳答案
你总是想获得相同的类型,而且我似乎明白,如果字符串中没有偏移量,你需要 UTC(明确这一点很重要)。我建议指定一个具有可选 UTC 偏移量和默认 UTC(零偏移量)的格式化程序,以防字符串中没有任何偏移量:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[X]")
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
String withoutZ = "2018-07-21T00:50:39";
Instant anInstant = formatter.parse(withoutZ, Instant::from);
System.out.println(anInstant);
String withZ = "2017-11-20T23:18:27.529Z";
Instant anotherInstant = formatter.parse(withZ, Instant::from);
System.out.println(anotherInstant);
输出:
2018-07-21T00:50:39Z 2017-11-20T23:18:27.529Z
格式模式字符串[X]
中的方括号表示偏移量X是可选的。秒上是否有小数由 ISO_LOCAL_DATE_TIME
处理。
我希望您知道 Date
类设计不佳且早已过时,因此通常您不应该想要一个,并且您只需要一个,因为您必不可少地需要一个您现在无法更改的旧版 API。在这种情况下,请按照您的问题从 Instant
进行最终转换。
通常用于可变日期/时间格式的技术包括:
- 依次尝试多种已知格式。
- 在确定使用哪种格式之前先尝试一下字符串。在你的情况下,你可能已经在
.endsWith("Z")
上分支,正如 Basil Bourque 的答案中已经建议的那样。 - 格式模式中的可选部分。
DateTimeFormatterBuilder.parseDefaulting()
用于分析字符串中可能缺少的部分。DateTimeFormatter.parseBest()
。
正如您所见,我在这里使用第 3 项和第 4 项。
关于java - 如何使用 Java 时间库将符合 ISO 的字符串解析为日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55540019/