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

Java DateTimeFormatter无法格式化自身解析的TemporalAccessor求助

DateTimeFormatter解析后无法重新格式化的通用解决方案

我正在创建一个简单的DateTimeFormatter,但它无法读取自身输出的内容。由于代码需要具备通用性,要处理带有完全不同字段的不同DateTimeFormatter实例,因此必须直接使用DateTimeFormatter而非LocalDate.format或YearMonth.format。

以下代码执行失败,报错:java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: YearOfEra

DateTimeFormatter yearMonthFormatter = DateTimeFormatter.ofPattern("yyyyMM");
TemporalAccessor yearMonthTemp = yearMonthFormatter.parse("200102");
String formatted = yearMonthFormatter.format(yearMonthTemp); //此处尝试格式化自身输出时失败

是否存在无需知晓日期时间模式内容即可实现上述需求的方法?即模式字符串"yyyyMM"并非固定值,而是作为参数传入。


问题原因

DateTimeFormatter.parse返回的TemporalAccessor仅包含解析过程中提取到的字段(示例中为Year和MonthOfYear),但格式化时yyyy模式需要YearOfEra字段,两者不匹配导致抛出异常。

通用解决方案

无需依赖具体模式内容,可通过以下方式将解析结果转换为完整的Temporal对象,确保格式化时能提供所有所需字段:

方法一:基于纪年系统构建完整时间对象

// 模式作为参数传入
String pattern = "yyyyMM";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
String input = "200102";

// 解析输入字符串
TemporalAccessor parsed = formatter.parse(input);

// 获取纪年系统,默认使用ISO纪年
Chronology chrono = parsed.query(TemporalQueries.chronology());
if (chrono == null) {
    chrono = IsoChronology.INSTANCE;
}

// 创建基础时间对象并合并解析字段
Temporal fullTemporal = chrono.dateEpochDay(0).with(parsed);

// 格式化输出
String formatted = formatter.format(fullTemporal);

方法二:根据精度匹配对应时间类型

通过解析结果的精度自动匹配Year、YearMonth、LocalDate等具体类型,确保字段完整性:

String pattern = "yyyyMM";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
String input = "200102";

TemporalAccessor parsed = formatter.parse(input);
Temporal temporal;

// 根据解析精度获取对应的具体时间类型
TemporalPrecision precision = parsed.query(TemporalQueries.precision());
if (precision == TemporalPrecision.YEAR) {
    temporal = Year.from(parsed);
} else if (precision == TemporalPrecision.MONTH_OF_YEAR) {
    temporal = YearMonth.from(parsed);
} else if (precision == TemporalPrecision.DAY_OF_MONTH) {
    temporal = LocalDate.from(parsed);
} else if (precision == TemporalPrecision.HOUR_OF_DAY || precision == TemporalPrecision.MINUTE_OF_HOUR) {
    temporal = LocalDateTime.from(parsed);
} else {
    // 其他精度情况直接使用解析结果
    temporal = parsed;
}

String formatted = formatter.format(temporal);

两种方法均无需提前知晓模式内容,可适配任意合法的日期时间格式。


内容的提问来源于stack exchange,提问作者The Shoe Shiner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:50:19