For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/year/pending/proposal-stable-formatting.md.
  • 简体中文
  • [Stable Formatting] stable-formatting ?

    中文标题:稳定格式化

    提案概览
    提案速览

    该提案为 Intl 格式化器引入 zxx 区域设置,以提供稳定、与实现无关的格式化输出,解决当前 Intl 行为缺乏稳定性的问题。它定义了 zxx 在各种 Intl API 中的具体格式化行为,例如日期使用 ISO-8601,并添加了 Intl.STABLE 属性以便使用。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    稳定格式化

    一个 TC39 提案,旨在为 ECMAScript 带来稳定的、受 Intl 启发的格式化选项。

    阶段: 2

    提案推动者: Eemeli Aro

    审阅者: Richard Gibson, Dan Minor

    演示文稿:

    动机

    Intl 格式化器以及 ECMA-402 定义的其他接口高度依赖实现,并且可能随时间发生变化。这意味着这些函数的输出不应被依赖,因为它们仅旨在提供“尽力而为”的结果,供立即向用户展示。

    然而,这并未阻止用户依赖字符串格式化器具有精确的输出结构,尤其是使用 en-US 区域设置的日期格式化。最近的例子可见于 2022年6月2022年11月。在 2023年6月 TC39-TG2此演示文稿中可以了解更多。

    缺乏稳定性也使得测试 Intl API 或依赖 Intl API 的网站和应用变得具有挑战性,因为实现差异可能导致不同环境中产生不同的结果。

    另外,有时需要为国际受众格式化值,或出于其他原因使用不特定于某个区域设置的格式。Intl 格式化器目前对此支持不佳。例如,StackOverflow 上关于如何使用 ISO-8601 格式格式化日期的最高票建议是使用瑞典语作为区域设置

    提议的解决方案

    在 ECMA-402 中定义每种格式化器在 zxx 区域设置下的行为。此区域设置标识符(表示“无语言内容;不适用”)是 ISO 639.2 中定义的有效 BCP 47 主要语言标签,但其行为在其他方面并未得到很好的定义。

    为便于使用,添加值为 "zxx"Intl.STABLE 属性。

    在可能的情况下,zxx 区域设置将使用有明确定义的标准行为,例如对日期格式化使用 ISO-8601。

    zxx 的“本地化”输出将避免在输出中包含实际本地化文本,例如完整写出的单位名称或月份名称。

    对于接受自然语言输入而不仅仅是产生自然语言输出的 Intl API(Collator、Segementer、String.prototype.toLocale{Lower,Upper}Case),我们不容易保证有用的稳定行为。目前不建议为它们提供 zxx 支持。

    new Intl.DateTimeFormat('zxx').format(new Date()) === '2023-09-01'
    
    (12345.67).toLocaleString(Intl.STABLE) === '12345.67'

    Intl.DateTimeFormat

    当使用 zxx 区域设置时,格式化输出与 Temporal 使用的输出匹配。为实现这一点,应用以下默认选项值:

    {
      calendar: 'gregory',
      numberingSystem: 'latn',
      hour12: false,
      hourCycle: 'h23'
    }

    在格式化输出中,适当时使用输入值的 RFC 9557 序列化,例如 2006-01-0215:04:052006-01-02T15:04:05.999+01:00[Europe/Paris]。仅使用时间和日期值的数字表示,如下所示:

    const dtf = new Intl.DateTimeFormat(Intl.STABLE, { month: "long" });
    dtf.format(new Date("2006-01-02")) === "1";

    hour12hourCycle 选项会被验证但忽略,并且格式化始终如同设置了 hour12: false 一样进行。

    dayPeriodweekdayera 选项会被验证但忽略。

    month 选项的值 'long''short' 被视为等同于其 '2-digit' 值,'narrow' 被视为等同于其 'numeric' 值。

    如果 timeZoneName 选项具有有效值,则无论选项值如何,都会使用规范的 IANA 时区标识符作为时区。

    如果 dateStyle 选项具有有效值,则格式化输出始终以格式如 2006-01-02 的日期开头。

    如果 timeStyle 选项具有有效值,则格式化输出始终以如下格式的时间结尾:

    • 'full''long'15:04:05+01:00[Europe/Paris]
    • 'medium'15:04:05
    • 'short'15:04

    如果同时设置了 dateStyletimeStyle 选项,则格式化输出由格式化后的日期、后跟 T (U+0054)、再后跟格式化后的时间组成。

    Intl.DisplayNames

    zxx 区域设置与有效格式化选项一起使用时,使用结构上有效的输入调用 of(code) 方法将表现为没有匹配的显示名称可用,并根据 fallback 选项返回请求的代码或 undefined

    Intl.DurationFormat

    zxx 区域设置与有效格式化选项一起使用时,格式化的持续时间是 '{number} {unit}' 条目的串联,由 ', ' 分隔,例如 2 year2 hour, 30 minute5 day, 1 millisecond,或者使用 style: 'digital' 时是以 : 分隔的时间值。

    Intl.ListFormat

    当使用 zxx 区域设置时,type 选项值会被验证但忽略,输出由 style 选项决定:

    • 'long''short':列表项由逗号后跟空格 , (U+002C U+0020) 分隔
    • 'narrow':列表项由空格 (U+0020) 分隔

    Intl.Locale

    对于 zxx 区域设置,所有字段和访问器返回其默认/回退值,除了 .getCalendars(),它返回 ['iso8601'] 而不是 ['gregory']

    Intl.NumberFormat

    当使用 zxx 区域设置时,格式化输出的数值部分始终满足 StrNumericLiteral 语法符号。在区域设置选项中,'latn' 用作 numberingSystem 选项的默认值。

    当与 style: 'currency' 选项一起使用时,输出包括数值、后跟一个空格 (U+0020)、再后跟 ISO 货币代码。currencyDisplay 选项值会被验证但忽略。如果 intl-currency-display-choices 提案被接受,则使用 currencyDisplay: 'never' 选项会从输出中省略除数值之外的所有内容。

    当与 style: 'percent' 选项一起使用时,输出包括数值后跟 U+0025 百分号字符。

    当与 style: 'unit' 选项一起使用时,输出由 unitDisplay 选项决定:

    • 'short':数值、后跟一个空格 (U+0020)、再后跟短单位标识符
    • 'narrow':数值、后跟短单位标识符
    • 'long':数值、后跟一个空格 (U+0020)、再后跟长单位标识符

    “长单位标识符”是 unit 选项值。

    “短单位标识符”是一个与语言环境无关的字符串,由 unit 选项值派生而来,需要根据 SI 单位等显式定义,例如 litrelterabyteTB。复合单位通过将 -per- 替换为斜杠 / (U+002F) 并将单位部分分别映射到其短单位标识符来形成。

    当与 notation: 'compact' 选项一起使用时,输出包括数值后跟适当的 SI 前缀:

    • 1012T (U+0054)
    • 109G (U+0047)
    • 106M (U+004D)
    • 103k (U+006B)

    compactDisplay 选项会被验证但忽略。

    useGrouping 选项会被验证但忽略,并且分组分隔符永远不会包含在输出中。

    Intl.PluralRules

    zxx 区域设置与有效格式化选项一起使用时,使用结构上有效的输入调用 select(number)selectRange(startRange, endRange) 方法将始终返回 'other'

    Intl.RelativeTimeFormat

    zxx 区域设置与有效格式化选项一起使用时,格式化的相对时间是 ISO 8601-2 持续时间,其第一个字符为加号 + (U+002B) 或连字符减 - (U+002D),例如 +P2Y(2年后)、-P1D(昨天)或 +PT10S(10秒后)。

    季度以月表示。

    Array.prototype.toLocaleString

    当使用 zxx 区域设置时,数组项以逗号 , (U+002C) 作为分隔符进行连接。

    备选方案

    向 ECMA-262 格式化器添加选项

    更改

    • Date.prototype.toString() 21.4.4.41
    • Number.prototype.toString([radix]) 21.1.3.6
    • BigInt.prototype.toString([radix]) 21.2.3.3

    以包含一个新的可选 options 参数:

    • Date.prototype.toString([options])
    • Number.prototype.toString([radix] [, options])
    • BigInt.prototype.toString([radix] [, options])

    并指定这三个函数应如何读取选项并不同地创建格式化结果字符串

    Date.prototype.toString 读取和尊重的选项将只是 toLocaleString 方法接受的选项的子集。例如,它不会读取 "localeMatcher"、"calendar"、"numberingSystem"、"hour12"、"dateStyle" 和 "timeStyle",但会读取 "hourCycle"、"timeZone"。提案可以决定是否读取 表 7 中列出的选项。

    Number.prototype.toStringBigInt.prototype.toString 读取和尊重的选项将只是 toLocaleString 方法接受的选项的子集。例如,它们不会读取 "localeMatcher"、"numberingSystem"、"style"、"currency"、"currencyDisplay"、"currencySign"、"unit"、"unitDisplay",但会读取 表 12 中列出的其他选项。

    Number 和 BigInt 方法也可以允许 options 参数替换 radix 参数,根据该参数的类型确定行为。

    这种方法不会包含 Intl 格式化器的 formatToParts 方法的任何等价物。

    添加“未确定”区域设置

    此提案的早期版本使用了“未确定”的 und 区域设置而不是 zxx。这也是一个有效的 ISO 639.2 语言标识符,但它被用作 CLDR 中的规范根区域设置标识符,例如在 java.util.Locale 中具有明确定义的行为。

    und 区域设置目前也被 Safari 支持为 en-US-u-va-posix 的别名,并且被 Chrome 和 Node.js 认可用于 Intl.Locale

    添加新的 ECMA-262 格式化方法

    与其修改 Date、Number 和 BigInt 现有的 toString 方法,不如为每个添加新的方法 toFormattedString,并带有如上定义的 options 参数。

    先前艺术