Java中ISO 8601格式日期字符串2021-07-27T09:58:51.000+0000解析问题
问题解答
1. 格式合规性判定
2021-07-27T09:58:51.000+0000是完全合规的ISO 8601日期格式。ISO 8601标准中时区偏移支持两种写法:
- 带冒号的格式:
±HH:mm - 不带冒号的格式:
±HHmm
你遇到的解析失败问题是Java部分内置默认解析器仅兼容带冒号的偏移格式,并非日期格式本身不符合规范。
2. 最优解析方案推荐
优先推荐Java 8+ 原生java.time包自定义格式化器方案,该方案线程安全、无第三方依赖、可兼容绝大多数ISO 8601变种格式,示例代码如下:
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.ChronoField; public class FlexibleIsoDateParser { // 兼容多种常见ISO 8601格式的解析器 private static final DateTimeFormatter FLEXIBLE_ISO_DATETIME = new DateTimeFormatterBuilder() // 匹配日期时间主体部分 .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) // 兼容不带冒号的时区偏移(如+0000) .optionalStart().appendOffset("+HHMM", "Z").optionalEnd() // 兼容带冒号的标准时区偏移(如+00:00) .optionalStart().appendOffset("+HH:MM", "Z").optionalEnd() // 无毫秒时默认补0,兼容不带毫秒的格式 .parseDefaulting(ChronoField.MILLI_OF_SECOND, 0) .toFormatter(); public static void main(String[] args) { // 测试你当前使用的格式 String dateStr = "2021-07-27T09:58:51.000+0000"; OffsetDateTime dateTime = OffsetDateTime.parse(dateStr, FLEXIBLE_ISO_DATETIME); System.out.println(dateTime); } }
其他可选方案
- 如果项目已依赖Apache Commons Lang3,可直接使用你测试中已验证可行的
DateUtils.parseDate方法,传入多种格式模板匹配不同ISO变种即可,注意该方法返回的是旧版java.util.Date类,可按需转换为java.time类。 - Joda Time方案仅推荐用于仍在使用Java 7及更低版本的老项目,Java 8及以上版本Joda Time官方已建议迁移到原生java.time包。
3. 测试结果差异说明
你之前的测试结果差异是由不同解析器支持的时区偏移格式不同导致:
OffsetDateTime.parse默认使用的ISO_OFFSET_DATE_TIME仅支持带冒号的时区偏移,因此识别+0000时报错SimpleDateFormat的Z模板对应不带冒号的±HHmm格式,因此测试用例002解析成功;XXX模板对应带冒号的±HH:mm格式,因此测试用例003解析失败
内容的提问来源于stack exchange,提问作者James Jithin
相关产品推荐
相关产品推荐

