Java 11部分场景下String转换LocalDateTime失败问题咨询
问题原因与解决方案
第一个葡萄牙语日期解析异常
根本原因
Java 8默认使用JRE内置的本地化数据,而Java 9及之后版本默认启用CLDR(通用区域数据仓库)作为本地化数据来源,二者对pt-MZ(葡萄牙语-莫桑比克) locale的月份拼写规则不同:
- Java 8 内置规则中1月的拼写为首字母大写的
Janeiro - CLDR规则中1月的拼写为全小写的
janeiro
所以解析到索引3的位置时(日期20后第一个字符是大写J,和CLDR规则不匹配)抛出异常。
修复方案
给DateTimeFormatter添加不区分大小写的解析配置即可兼容两种规则:
DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern("d MMMM yyyy HH:mm") .toFormatter() .withLocale(locale);
如果不想修改代码,也可以在JVM启动参数中添加-Djava.locale.providers=COMPAT,强制使用Java 8兼容的本地化数据源。
第二个带时区的日期解析异常
根本原因
同样是CLDR本地化数据变更导致的规则差异:Java 8中模式符z可以匹配UTC+01:00这类带偏移的时区格式,但Java 11中z仅能匹配时区简称(如UTC、CST),无法匹配带数字偏移的UTC格式,因此解析到对应偏移位置时抛出异常。
修复方案
修改日期匹配模式,显式指定UTC偏移的匹配规则:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss ('UTC'XXX)");
如果需要同时兼容Java 8和Java 11的运行环境,也可以添加JVM启动参数-Djava.locale.providers=COMPAT回退到旧的本地化规则。
内容的提问来源于stack exchange,提问作者Nguyễn Quang Lê
相关产品推荐
相关产品推荐

