解析ISO_INSTANT和类似的日期时间字符串

2022-09-03 09:50:51

我昨天创建了这个奇妙的静态方法,它工作得很好 - 昨天

但是,今天它给了我这个错误。我猜它来自Z之前的0s太多了。

任何人都可以推荐如何以简洁的方式解析(Java 8)这种类型的格式日期 - 请记住,它昨天也有效,所以也是一种有效的格式?StringISO_INSTANTString

Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {NanoOfSecond=0, InstantSeconds=1443451604, MilliOfSecond=0, MicroOfSecond=0},ISO of type java.time.format.Parsed
at java.time.LocalDate.from(LocalDate.java:368)
at java.time.LocalDateTime.from(LocalDateTime.java:456)
... 9 more

在输入时间引发异常:“2015-09-28T14:46:44.000000Z”

/**
 *
 * @param time the time in RFC3339 format (e.g. "2013-07-03T14:30:38Z" )
 * @return
 */
public static LocalDateTime parseTimeINSTANT(String time) {
    DateTimeFormatter f = DateTimeFormatter.ISO_INSTANT;
    return LocalDateTime.from(f.parse(time));
}

enter image description here


答案 1

您正在解析与 ISO 时刻一致的字符串,因此您需要将结果存储在 中,而不是 :InstantLocalDateTime

public static Instant parseTimeINSTANT(String time) {
    DateTimeFormatter f = DateTimeFormatter.ISO_INSTANT;
    return Instant.from(f.parse(time)); // could be written f.parse(time, Instant::from);
}

请注意,此格式化程序可以正确处理小数秒,因此您无需删除它们。引用 DateTimeFormatter.ISO_INSTANT Javadoc (强调我的):

解析时,至少需要时间到秒字段。解析从 0 到 9 的小数秒

至于为什么它昨天而不是今天有效,我不知道......


答案 2

只是为了帮助以后看到这个问题的人。

您需要将 ISO 日期解析为 ,将其转换为对象,然后从中创建一个提供区域 ID 的。我在这里设置了UTC的区域ID。InstantInstantLocalDateTime

代码如下

public static LocalDateTime getISODate(String dateString) {
    DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_INSTANT;
    Instant dateInstant = Instant.from(isoFormatter.parse(dateString));
    LocalDateTime date = LocalDateTime.ofInstant(dateInstant, ZoneId.of(ZoneOffset.UTC.getId()));

    return date;
}