Java迁移Joda Time至java.time时OffsetDateTime解析报错求助
问题:Joda Time迁移至java.time解析带Z时间字符串报错
原有Joda Time代码(可正常运行):
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import java.util.Date; DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); String transactionTime = "2019-02-26T13:43:12Z"; Date txnTime = DATE_TIME_FORMATTER.parseDateTime(transactionTime).toDate();
迁移至java.time时编写的代码(运行报错):
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); String transactionTime = "2019-02-26T13:43:12Z"; OffsetDateTime txnTime = OffsetDateTime.from( OffsetDateTime.parse(transactionTime, DATE_TIME_FORMATTER) .toInstant());
报错信息:
Text '2019-02-26T13:43:12Z' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2019-02-26T13:43:12 of type java.time.format.Parsed
移除自定义DATE_TIME_FORMATTER后代码可正常运行:
OffsetDateTime txnTime = OffsetDateTime.from( OffsetDateTime.parse(transactionTime).toInstant() );
解决方案
错误原因
你在自定义格式化器里把Z用单引号括起来了('Z'),这会让java.time的DateTimeFormatter把Z当成普通文本字符处理,而不是识别为UTC时区偏移标记(代表+00:00)。解析后得到的结果没有时区偏移信息,自然无法转换为需要时区偏移的OffsetDateTime类型。
正确实现方式
1. 修复自定义格式化器
去掉Z的单引号,改用格式符X让格式化器识别它为ISO 8601时区偏移标记:
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; // 用X替代'Z',正确识别UTC偏移 DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX"); String transactionTime = "2019-02-26T13:43:12Z"; // 直接解析为OffsetDateTime,无需多余转换 OffsetDateTime txnTime = OffsetDateTime.parse(transactionTime, DATE_TIME_FORMATTER); // 若需兼容旧代码转为java.util.Date Date date = Date.from(txnTime.toInstant());
格式符X可匹配多种ISO 8601时区格式,包括Z、+01:00、-0500等。
2. 更简洁的推荐写法
你的目标时间字符串是标准ISO 8601格式,OffsetDateTime的默认解析器已经原生支持该格式,完全不需要自定义格式化器,直接用OffsetDateTime.parse(transactionTime)即可,就像你测试的正常代码那样。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

