解析2021-01-15T19:00:00+0000格式日期抛出解析异常如何解决?
报错根因
OffsetDateTime.parse()和ZonedDateTime.parse()的默认解析器遵循ISO 8601扩展格式规范,要求时区偏移段必须使用±HH:mm的带冒号格式(比如+00:00)。传入的字符串2021-01-15T19:00:00+0000的偏移段为+0000,缺少小时和分钟之间的冒号,索引19的位置刚好是偏移段起始位置,不符合默认格式要求,因此抛出解析异常。
该字符串属于ISO 8601基本格式的日期时间,对应格式匹配规则为yyyy-MM-dd'T'HH:mm:ssZ。
注意:java.time包下的默认时间解析器不会自动兼容基本格式和扩展格式的偏移写法,必须显式指定格式或做格式转换。
可行解析方案
自定义格式器解析(通用性最好,推荐)
构造与输入字符串格式完全匹配的DateTimeFormatter实例,传入parse方法即可,无需修改原始输入:import java.time.OffsetDateTime import java.time.ZonedDateTime import java.time.format.DateTimeFormatter val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ") // 解析为OffsetDateTime val offsetTime = OffsetDateTime.parse("2021-01-15T19:00:00+0000", dateFormatter) // 解析为ZonedDateTime val zonedTime = ZonedDateTime.parse("2021-01-15T19:00:00+0000", dateFormatter)该方案可以同时兼容
±HHmm格式的所有偏移值,包括非UTC时区的输入比如2021-01-15T19:00:00+0800。预处理字符串适配默认格式
如果不想额外定义格式器,可以手动给偏移段补全冒号,转换为默认解析器支持的扩展格式后再解析:val rawInput = "2021-01-15T19:00:00+0000" // 偏移段固定为5位长度,在倒数第二位前插入冒号 val standardInput = StringBuilder(rawInput).insert(rawInput.length - 2, ":").toString() val offsetTime = OffsetDateTime.parse(standardInput) val zonedTime = ZonedDateTime.parse(standardInput)注意:该方案需要提前判断输入的偏移格式,如果输入可能出现
Z(代表UTC时区)的写法,需要额外加分支判断,否则会出现下标计算错误。
内容的提问来源于stack exchange,提问作者Rahul Matte
相关产品推荐
相关产品推荐

