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

Oracle JDK 17下dd MMM yyyy格式日期解析失败是否为Bug?

问题原因

这个问题不属于JDK Bug,是Java版本迭代过程中默认本地化数据源变更导致的预期行为差异:

  • Java 11及更早版本默认优先使用JDK自带的兼容型本地化数据,英国英语(Locale.UK)区域下9月的短缩写为Sep,和你代码中的字符串匹配
  • 从Java 16开始,JDK默认启用Unicode CLDR(通用区域数据仓库)作为第一优先级的本地化数据源,该规则下英国英语区域9月的短缩写调整为Sept,因此26 Sep 2021无法被正常解析,抛出索引3位置的解析异常。

你可以运行以下代码验证当前环境下的月份缩写规则:

import java.text.DateFormatSymbols;
import java.util.Locale;

public class CheckMonthAbbr {
    public static void main(String[] args) {
        String[] shortMonths = DateFormatSymbols.getInstance(Locale.UK).getShortMonths();
        // 索引0对应1月,索引8对应9月
        System.out.println("9月短缩写:" + shortMonths[8]);
    }
}

在Oracle JDK 17环境下运行输出为Sept。


解决方案

根据你的业务场景可以选择以下任意一种方案:

  1. 适配新缩写规则
    把代码中涉及9月的Sep字符串统一替换为Sept即可正常解析。
  2. 兼容旧本地化规则
    启动Java应用时添加JVM参数,优先使用旧版兼容本地化数据:
    -Djava.locale.providers=COMPAT,CLDR
    
    该方案不需要修改业务代码,保持原有日期字符串格式即可正常运行。
  3. 自定义固定解析规则
    如果你需要保证不同JDK版本下解析逻辑完全一致,不受系统本地化配置影响,可以通过DateTimeFormatterBuilder自定义月份缩写映射:
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.time.format.DateTimeFormatterBuilder;
    import java.time.temporal.ChronoField;
    import java.util.Locale;
    import java.util.Map;
    
    public class Main {
        public static void main(String[] args) {
            // 自定义固定的月份缩写映射,不受本地化数据源影响
            Map<Long, String> monthAbbrMap = Map.ofEntries(
                    Map.entry(1L, "Jan"), Map.entry(2L, "Feb"), Map.entry(3L, "Mar"),
                    Map.entry(4L, "Apr"), Map.entry(5L, "May"), Map.entry(6L, "Jun"),
                    Map.entry(7L, "Jul"), Map.entry(8L, "Aug"), Map.entry(9L, "Sep"),
                    Map.entry(10L, "Oct"), Map.entry(11L, "Nov"), Map.entry(12L, "Dec")
            );
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                    .appendPattern("dd ")
                    .appendText(ChronoField.MONTH_OF_YEAR, monthAbbrMap)
                    .appendPattern(" yyyy")
                    .toFormatter(Locale.UK);
            
            LocalDate date = LocalDate.parse("26 Sep 2021", formatter);
            System.out.println(date); // 输出 2021-09-26
        }
    }
    

内容的提问来源于stack exchange,提问作者Dan MacBean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:06:09