You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:31:11