使用DateTimeFormatter解析无时间日期报错:Unable to obtain LocalTime from TemporalAccessor
问题解决:Unable to obtain LocalTime from TemporalAccessor异常
问题原因
你用ZonedDateTime.parse()解析仅含日期的字符串时出错,核心原因是ZonedDateTime需要日期+时间+时区的完整信息,但你的格式化器df只解析了日期部分——哪怕设置了时区,缺失的时、分、秒等时间字段还是会导致无法构造ZonedDateTime,从而抛出异常。
解决方案
有两种直接的修复方式:
方案1:先解析为LocalDate,再转换为ZonedDateTime
先把日期字符串解析成仅包含日期的LocalDate,再调用atStartOfDay()方法指定UTC时区的午夜时间(00:00:00),生成完整的ZonedDateTime:
public static void main(String[] args) throws Exception { DateTimeFormatter standardFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US).withZone(ZoneOffset.UTC); DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.US); // 先解析为仅含日期的LocalDate LocalDate localDate = LocalDate.parse("2022-11-23", df); // 转换为UTC时区的00:00:00时刻 ZonedDateTime utcDateTime = localDate.atStartOfDay(ZoneOffset.UTC); System.out.println(utcDateTime.format(standardFormatter)); }
方案2:用DateTimeFormatterBuilder设置默认时间字段
通过DateTimeFormatterBuilder给格式化器添加默认的时间值(时、分、秒都设为0),这样解析日期字符串时会自动补充缺失的时间信息:
public static void main(String[] args) throws Exception { DateTimeFormatter standardFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US).withZone(ZoneOffset.UTC); // 构造带默认时间的格式化器 DateTimeFormatter df = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd") .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .toFormatter(Locale.US) .withZone(ZoneOffset.UTC); ZonedDateTime utcDateTime = ZonedDateTime.parse("2022-11-23", df); System.out.println(utcDateTime.format(standardFormatter)); }
两种方案运行后都会输出:2022-11-23T00:00:00.000Z,完全符合你需要的ISO8601格式。
内容的提问来源于stack exchange,提问作者basin
相关产品推荐
相关产品推荐

