案例 ICU 79 升级笔记:UnicodeString 将被标 final、H24 弃用,从 78.3 到 79 要验证的 5 件事

2026-10-21 00:04:11

ICU 79 升级笔记:C++ 类标 final、H24 弃用,78.3 到 79 的验证排期

谁会受影响

  • 编译 ICU4C 的:需要 C++17(已测到 C++23),Windows 最低 Win7。
  • 直接用 ICU4J 的:从 ICU 78 起最低 Java 版本由 8 提到 11(ICU-23072),当前支持 Java 11..25;Android API 21+ 可能要做 library desugaring。
  • 继承过 ICU C++ 类的:ICU 79 计划把长期标注「不适合被继承」的类(例如 UnicodeString)声明为 final,现有子类会直接编译失败(ICU-23284)。
  • 用了 H24 小时制、week-of-year、pre-Meiji 日本年号的:输出会变(CLDR-18303 / CLDR-18275 / CLDR-11400、ICU-23341)。
  • 依赖 ICU4J Java 序列化的:从 ICU 80 起不再保证跨版本兼容(ICU-23484)。
  • 用了 UnicodeSet pattern 冷门写法的:边角用例的解析结果会变(UTS #61、ICU-23509)。

具体变更

版本现状

ICU 78.3 是维护版,2026-03-17 发布,主要更新 CLDR 48.2,另修一个 C++ code point iterator bug,tzdata 2026a(ICU-23330)。Maven 坐标 com.ibm.icu:icu4j:78.3。维护版不动 API,下一大版本就是 79。

ICU 79 RC 于 2026-09-25 发布,正式版预计 2026 年 10 月底。下载 tag:release-79.1rc,文档见 ICU 79 download。初始发布库版本 79.1,后续维护版是 79.2、79.3。

79 的内容面:升级 Unicode 18,新增两个大型历史文字 (Small) Seal 与 Jurchen,新货币符号 RUFIYAA、UAE DIRHAM、OMANI RIAL,9 个新 emoji,line & grapheme cluster breaking 分段改进;升级 CLDR 49 locale 数据。

平台门槛

ICU4C 需要 C++17,已测到 C++23;Windows 最低 Windows 7。

ICU4J 最低 Java 11,支持 Java 11..25(至少);Android API 21+ 可能需 library desugaring。

ICU 79 计划中的破坏性变更

  • C++ 类标 final:CLDR 与 ICU 计划把长期文档注明「不适合被继承」的 C++ 类(例如 UnicodeString)声明为 final。这些 API 早于 C++ 的 final 关键字,改动的目的是让 API 更稳健,代价是破坏那些建立了不受支持子类的用户。见 ICU-23284。
  • 弃用 H24:不常见的 H24 小时循环被弃用,行为改成与 H23 一致(CLDR-18303)。
  • week-of-year 一律 ISO:周编号统一遵循 ISO 规则(CLDR-18275)。
  • ICU4J 序列化:ICU-TC 同意从 ICU 80 起逐步取消 ICU4J 的跨版本 Java 序列化兼容保证。理由是 Java 默认序列化机制带来大量维护开销、限制内部类重构与演进,并有已知安全风险。详见 ICU-23484。

CLDR advanced warnings 里还有更多待办项。

已经发生的行为变化

  • UnicodeSet pattern:为配合 Draft UTS #61(Unicode Set Notation)标准化,ICU 中 UnicodeSet pattern 解析有多处变更,某些边角用例会改变原本可接受的 pattern 的行为(详见 User Guide 的 UnicodeSet 章节)。同时支持新语法:更可读的转义 \N{20AC:EURO SIGN} 与 \N{20AC:€:EURO SIGN},更可读的 not-property-value 表达式 [:Property≠Value:] 与 \p{Property≠Value}(ICU-23509)。
  • 序数日期:支持序数日期格式化(如 December 25th)以及非纯数字的日期(CLDR-7408 & ICU-23364)。
  • pre-Meiji 日本年号移除:因数据不确定性被移除,明治前日期惯例使用公历(CLDR-11400、ICU-23341、ICU-23108)。
  • 78 的背景一句:ICU 78 于 2025-10-30 发布,升级 Unicode 17 + CLDR 48;其中 Locale 类优化后常见 locale ID 的对象只占 40 字节(原来至少 224 字节,ICU-20392),ICU4J 新增 Segmenter API 替代 BreakIterator。

性能

行断行(line break)的反向迭代不再需要计算从字符串开头到迭代起点之间的所有断点(ICU-23478)——这个回归从 ICU 62 起就存在。79 另有大量 bug 修复,以及性能、堆内存、多线程、OOM 处理方面的改进。

构建与运维

  • ICU data 裁剪:ICU4J 从 ICU4C 移植了数据文件加载的 tracing,可用来查明需要哪些数据文件,从而精简 ICU 数据(ICU-20656)。
  • lifetimebound:ICU4C common 库的公开 API 按需标注了 U_LIFETIME_BOUND,有助于提前发现对象生命周期错误(ICU-23310);代价是编译告警可能变多。
  • ICU4J LinkUtilities:新增类,实现 UTS #58(Unicode Link Detection and Formatting: URLs and Email Addresses)(ICU-23431)。
  • MessageFormat 2.0:C++ 与 Java 的 CLDR MessageFormat 2.0 实现更新到 CLDR 49,部分 API 仍是 technology preview。

tzdata 与 CLDR

tzdata 2026d(2026-09)。CLDR 49 与 ICU 79 一同发布,新增 3 个单位:milliinch(US mil)、poundal、syne。Unicode 18.0.0 于 2026-09-16 发布;ICU4X 2.3 于 2026-08-14 发布,是独立仓库的 Rust 实现,不在这次升级路径上。

怎么验证与应对:92 天窗口里的排期

  1. 先跑 78.3。维护版不动 API,只带 CLDR 48.2 与 tzdata 2026a,适合当基线。Java 侧把依赖换成 com.ibm.icu:icu4j:78.3,回归结果作为对照。
  2. 把 79 RC 放进测试环境,用同一批用例比结果,重点看 collation 排序、日期时间格式(H23/H24、序数日期、日本年号)、week-of-year、UnicodeSet pattern 解析这几块。
  3. 编译侧:确认构建链支持 C++17;如果开了 -Werror,U_LIFETIME_BOUND 带来的新告警要么修,要么按需关掉。ICU4J 侧检查 Android desugaring 配置。
  4. 继承侧:把自建的 UnicodeString 等子类改成组合或内部包装,赶在 79 正式版前验证通过。
  5. 持久化侧:ICU 80 起不再保证跨版本 Java 序列化兼容,别把 ICU4J 对象当作持久化格式写盘。
复制全文 生成海报 ICU Unicode CLDR 国际化 i18n 升级迁移

推荐文章

程序员茄子在线接单