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
相关产品推荐
相关产品推荐

