解决DateTimeParseException:将单毫秒位时间字符串转为三位格式
问题解决:解析可变长度毫秒的时间字符串
你的问题出在当前的DateTimeFormatter要求毫秒部分必须是三位(SSS),但输入的2018-11-05T06:14:10.6-05:00里毫秒只有一位,导致解析失败。下面提供两种可行的解决方式:
方案一:构建支持可变长度毫秒的格式化器
直接使用DateTimeFormatterBuilder创建能匹配1-3位毫秒的格式,解析后再按需格式化为三位毫秒的字符串:
// 构建灵活的格式化器,支持1-3位毫秒 DateTimeFormatter flexibleFormatter = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd'T'HH:mm:ss") .appendFraction(ChronoField.MILLI_OF_SECOND, 1, 3, true) // 允许1到3位毫秒 .appendPattern("XXXXX") .toFormatter(); String s = "2018-11-05T06:14:10.6-05:00"; OffsetDateTime offsetDateTime = OffsetDateTime.parse(s, flexibleFormatter); // 如果需要转换为三位毫秒的格式输出 String formattedStr = offsetDateTime.format( DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX") ); // formattedStr 结果为 "2018-11-05T06:14:10.600-05:00"
方案二:预处理字符串补全毫秒位数
手动修改原字符串,将毫秒部分补零到三位,再用原格式化器解析:
private static String fixMillisecondLength(String timeStr) { int dotPos = timeStr.indexOf('.'); if (dotPos == -1) { // 无毫秒部分,添加.000 int zonePos = timeStr.contains("-") ? timeStr.lastIndexOf('-') : timeStr.indexOf('+'); return timeStr.substring(0, zonePos) + ".000" + timeStr.substring(zonePos); } int zonePos = timeStr.indexOf('-', dotPos); if (zonePos == -1) zonePos = timeStr.indexOf('+', dotPos); String millis = timeStr.substring(dotPos + 1, zonePos); // 补零到三位 String paddedMillis = String.format("%3s", millis).replace(' ', '0'); return timeStr.substring(0, dotPos + 1) + paddedMillis + timeStr.substring(zonePos); } // 使用示例 String original = "2018-11-05T06:14:10.6-05:00"; String fixedStr = fixMillisecondLength(original); // fixedStr 结果为 "2018-11-05T06:14:10.600-05:00" // 现在可以用原格式化器解析 OffsetDateTime oDAtOffset = OffsetDateTime.parse(fixedStr, DATE_TIME_FORMATTER);
方案对比
- 方案一更推荐,完全利用Java时间API的能力,无需手动处理字符串边界,代码更健壮。
- 方案二适合需要严格保持原字符串结构、仅补全毫秒位的场景,但要注意处理各种边缘情况(比如无时区符号、毫秒位是两位等)。
内容的提问来源于stack exchange,提问作者uniwinux
相关产品推荐
相关产品推荐

