质量外展预告 - JDK 20-23:支持 Unicode CLDR 版本 42

OpenJDK 质量小组正在推广使用 OpenJDK 构建测试 FOSS 项目,以此作为提高版本整体质量的一种方式。此预告是发送给相关项目的定期通信的一部分。要了解有关该计划的更多信息以及如何加入,请在此查看。

JDK 20 - 支持 Unicode CLDR 版本 42

JDK 的区域设置数据基于 Unicode 联盟的 Unicode 通用区域设置数据存储库 (CLDR)。如2022 年 12 月质量外展时事通讯中所述,JDK 20 将 CLDR 升级到版本 42,该版本于 2022 年 10 月发布。此版本包括“更复杂的空格处理”,它用不间断空格 (NBSP / \u00A0) 或窄不间断空格 (NNBSP / \u202F) 替换常规空格

  • a 和时间之间的时钟格式中
  • 在 {0} 和单位之间的单位格式中
  • 在西里尔语日期格式中,在年标记(如 г)之前

其他显着变化包括

因此,生成或解析区域设置相关字符串(如格式化的日期和时间)的生产和测试代码可能会以可能中断的方式更改行为(例如,当解析带有常规空格的手工日期时间字符串时,但解析器现在需要 NBSP 或 NNBSP)。由于预期的字符串和实际字符串在各种文本表示形式中看起来非常相似甚至完全相同,因此问题可能难以分析。要检测并修复这些问题,请务必使用以不同方式显示不同类型空格的文本编辑器。

如果在升级到 JDK 20 时无法实现所需的修复,请考虑使用 JVM 参数 -Djava.locale.providers=COMPAT 以使用旧版区域设置数据。请注意,这会限制某些与区域设置相关功能,并将其视为一种临时解决方法,而不是一种适当的解决方案。此外,COMPAT 选项最终将在未来移除。

同样重要的是要记住,此类区域设置数据会定期更新,因此程序自行解析/组合区域设置数据的程序应定期使用每个 JDK 版本进行检查。

有关更多详细信息,请查看JDK-8284840

JDK 23 更新 - 松散匹配空格分隔符

从 JDK 23 开始,日期/时间字符串的解析允许对空格进行松散匹配。此增强功能主要用于解决上面描述的问题。松散匹配在 java.time.formatjava.text 包中两个日期/时间解析器的宽松解析样式中执行。在默认的严格解析样式中,这些空格与之前一样被视为不同。

要利用 java.time.format 包中的宽松匹配,应用程序需要通过调用 DateTimeFormatterBuilder.parseLenient() 显式设置宽松性

var dtf = new DateTimeFormatterBuilder()
	.parseLenient()
	.append(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT))
	.toFormatter(Locale.ENGLISH);

java.text 包中,默认解析模式是宽松的,应用程序将能够自动解析所有空格分隔符(即,默认行为随此功能而改变)。如果需要严格解析文本,则可以执行

var df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.ENGLISH);
df.setLenient(false);

有关更多详细信息,请查看 JDK-8324665

~