Java标准库解析含闰秒的LocalDateTime报错,如何解决?
解析包含闰秒的LocalDateTime字符串
直接使用默认的DateTimeFormatter解析2016-12-31 23:59:60会抛出异常,核心原因是Java标准库的LocalDateTime基于ISO-8601日历系统,该系统定义分钟内的秒数范围为00-59,不包含闰秒的60秒值。
可行的处理方案
虽然LocalDateTime本身不支持闰秒,但针对已知的过去闰秒(如2016年的这次闰秒),可以通过以下方式用Java标准库处理:
- 手动预处理字符串:先检查时间字符串是否包含
:60的秒数片段,将其替换为:59后再解析,之后可自行标记该时间对应闰秒,示例代码:String timeStr = "2016-12-31 23:59:60"; boolean isLeapSecond = timeStr.endsWith(":60"); if (isLeapSecond) { timeStr = timeStr.replace(":60", ":59"); } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime dt = LocalDateTime.parse(timeStr, formatter); // 后续可通过isLeapSecond变量记录闰秒信息 - 自定义宽松解析器:通过
DateTimeFormatterBuilder定义允许秒数为60的解析规则,配合ResolverStyle.LENIENT将闰秒时间自动调整为下一分钟的起始点(但会丢失闰秒标记),示例代码:DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd HH:mm:") .appendValue(ChronoField.SECOND_OF_MINUTE, 2, 2, SignStyle.NEVER) .toFormatter() .withResolverStyle(ResolverStyle.LENIENT); // 解析后dt会是2017-01-01T00:00:00 LocalDateTime dt = LocalDateTime.parse("2016-12-31 23:59:60", formatter); - 使用Instant处理UTC闰秒:如果需要对应UTC时间的精确映射,可以使用
Instant。不过Java的Instant基于平滑UTC(忽略闰秒的连续时间轴),会将闰秒时间2016-12-31T23:59:60Z映射为与2017-01-01T00:00:00Z相同的时间戳,无法显式区分闰秒。
内容的提问来源于stack exchange,提问作者Gabriel Carrera
相关产品推荐
相关产品推荐

