Intl Sequence Units ?
中文标题:Intl 序列单位
- 阶段: 未分阶段
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
本提案解决了 Intl.NumberFormat 中缺乏标准化方式来格式化测量单位序列(例如英尺和英寸)的问题,目前需要手动组合且在不同区域设置下容易出错。它扩展了 Intl.NumberFormat 以接受复合单位标识符(如 'foot-and-inch')和对象输入用于 format/formatToParts,并规定了符号一致性和中间单位为整数的验证规则。DurationFormat 处理的时间单位。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
Intl 序列单位
本提案规定了在 Intl.NumberFormat 中格式化测量单位序列(例如“英尺和英寸”或“米和厘米”)的机制。
- 阶段:2
- champion:@sffc
- 规范
- 原始 ECMA-402 问题
演示文稿:
动机
测量系统经常使用多个单位顺序排列来表达单一量值。示例包括:
- 人的身高:“5 英尺 11 英寸”或“1 米 80 厘米”
- 质量:“2 磅 4 盎司”
当前 ECMAScript 实现要求手动组合多个 Intl.NumberFormat 的输出。这种方法引入了与本地化分隔符、单位排序和复数形式一致性相关的风险,这些在不同区域设置中差异很大。本提案通过提供用于多单位格式化的标准化接口来解决这些需求。
例如,要格式化“5 英尺 11 英寸”,目前开发人员必须编写:
虽然这是可行的,但它不够符合人体工程学,并且容易出错:
- 它需要创建和管理多个
Intl.NumberFormat实例。 - 开发人员必须手动确保正确的单位顺序。
- 它不会自动处理整个序列中的符号显示(例如,仅在第一个单位上显示负号)。
提议的解决方案
Intl.NumberFormat 被扩展以支持由 -and- 分隔符连接的复合单位标识符(例如,foot-and-inch、meter-and-centimeter、pound-and-ounce)。
当指定序列单位时,format 和 formatToParts 接受一个 JavaScript 对象作为输入。对象的每个属性必须对应于序列中标识的子单位。
示例
技术语义
序列单位的格式化过程遵循以下步骤:
- 验证:序列必须是受支持单位的有效组合,这些单位测量相同的物理量并按量级降序排列。受支持的序列在规范中明确列出(例如,
foot-and-inch、kilogram-and-gram)。请注意,时间单位被排除在序列单位之外,因为它们由Intl.DurationFormat管理。 - 提取:根据子单位键从输入对象中获取值。
- 组件格式化:
- 中间单位:必须是整数,并按整数格式化。
- 终端单位:根据配置在
Intl.NumberFormat实例上的舍入和小数设置进行格式化。
- 组合:使用
Intl.ListFormat(type: "unit"和指定的unitDisplay样式)连接生成的组件字符串,以确保符合区域设置的连接词和间距。
错误处理
format 或 formatToParts 的输入必须包含单位标识符中定义的每个子单位的值。属性按其在单位标识符序列中出现的顺序读取。如果必需属性为 undefined 或缺失,则立即抛出 TypeError。
读取所有属性并将其转换为数字后,进行两次最终验证:
- 混合符号:所有子单位必须具有相同的符号。混合正负值(例如,
{ foot: 5, inch: -11 })会抛出RangeError。 - 中间整数:所有中间子单位(除最后一个之外的所有子单位)必须是整数。提供非整数中间值(例如,
{ foot: 5.5, inch: 6 })会抛出RangeError。
与 Intl 单位协议的集成
本提案与 Intl 单位协议 兼容。使用该协议时,value 属性接受将子单位映射到其各自量级的对象:
与 Amount 提案的集成
本提案与 Amount 提案保持一致。为了支持序列单位,Amount 实例封装一个结构化值(一个将子单位映射到量级的对象),而不是标量数值。
先前工作
序列单位的格式化要求定义在 Unicode 技术标准 #35(LDML)中,第 单位序列(混合单位) 节。TR35 指定使用本地化的 listPattern 数据来组合这些序列,本提案为 ECMAScript 实现了这一点。
未来方向
附加单位
一些常用于序列的单位,例如 arcminute 和 arcsecond,目前并非 ECMA-402 中的受支持单位。格式化角度测量值,如“5° 30′ 12″”(概念上会使用 degree-and-arcminute-and-arcsecond),需要单独的提案将 arcminute 和 arcsecond 添加到受支持的单单位标识符列表中,然后才能将它们用作序列单位。
考虑的替代方案
标量输入与自动分区
接受单个标量值(例如 6.5)并自动将其分区为序列单位(例如“6 英尺 6 英寸”)的可能性已被评估并拒绝,原因如下:
- 输入歧义:标量输入并不固有地定义它们代表序列中的哪个子单位(例如,在
foot-and-inch中,不清楚6.5是指英尺还是英寸)。 - 转换数据不完整:引擎可能不具备所有可能单位组合的转换因子,特别是对于自定义或未来的单位。这排除了可靠的自动分区。
- 精度和舍入:通过浮点运算进行自动分区可能会引入错误。要求预先分区的输入可确保输出准确反映开发人员的数据。