ECMA-402 草案 / 2025年10月22日

ECMAScript® 2026 国际化 API 规范

如何参与本规范编制

本规范在 GitHub 上由 ECMAScript 社区协作开发。您可以通过以下几种方式参与本规范的编写:

更多关于本文档编写方式的信息,请参见 卷尾

简介

本规范的源码可在 https://github.com/tc39/ecma402 获取。

《ECMAScript 2026 国际化 API 规范》(ECMA-402 第13)为ECMA-262补充了关键的语言敏感功能。其功能借鉴了成熟的国际化 API,例如Unicode 国际化组件(ICU)库https://unicode-org.github.io/icu-docs/)、.NET 框架以及 Java 平台。

第一版 API 基于 Nebojša Ćirić 和 Jungshik Shin 的提案,于 2010 年 9 月由 Ecma TC39 临时小组开发。

第二版 API 于 2015 年 6 月被大会采纳,作为 ECMAScript 第6的补充。

第三版 API 是在 Ecma TC39 推行年度发布节奏和开放开发流程后发布的首个版本。ECMA-402 源文件被转换为纯文本文档,作为后续完全在 GitHub 上开发的基础。在该标准开发的一年里,提交了数十个拉取请求和议题,包括若干 bug 修复、编辑修订及其他改进。此外,还开发了许多辅助工具,包括 Ecmarkup、Ecmarkdown 和 Grammarkdown。

许多机构的数十位成员在 Ecma TC39 内对本版及以往版本做出了重要贡献。同时,一个充满活力的社区也在支持 TC39 的 ECMAScript 工作。社区成员审查了众多草案,提交了大量 bug 报告,进行实现实验,贡献了测试套件,并向全球开发者宣传 ECMAScript 国际化。不幸的是,无法一一列举并致谢所有参与的个人和机构。

Norbert Lindenberg
ECMA-402,第一版项目编辑

Rick Waldron
ECMA-402,第二版项目编辑

Caridy Patiño
ECMA-402,第三、四、五版项目编辑

Caridy Patiño, Daniel Ehrenberg, Leo Balter
ECMA-402,第六版项目编辑

Leo Balter, Valerie Young, Isaac Durazo
ECMA-402,第七版项目编辑

Leo Balter, Richard Gibson
ECMA-402,第八版项目编辑

Leo Balter, Richard Gibson, Ujjwal Sharma
ECMA-402,第九版项目编辑

Richard Gibson, Ujjwal Sharma
ECMA-402,第十版项目编辑

Richard Gibson, Ujjwal Sharma
ECMA-402,第十一版项目编辑

Ben Allen, Richard Gibson, Ujjwal Sharma
ECMA-402,第十二版项目编辑

Ben Allen, Richard Gibson, Ujjwal Sharma
ECMA-402,第十三版项目编辑

1 范围

本标准定义了 ECMAScript 对象的应用程序接口,这些对象支持需要适应不同人类语言和国家所用语言及文化习惯的程序。

2 符合性

本规范的符合性实现必须遵循 ECMA-262,并必须提供和支持本规范中描述的所有对象、属性、函数和程序语义。本规范无意允许任何被 ECMA-262 明令禁止的行为,若有此类冲突应视为编辑错误,而不是对 ECMA-262 约束的覆盖。

符合性实现允许提供本规范之外的其他对象、属性和函数。特别地,符合性实现允许为规范中描述的对象提供未在本规范中描述的属性及其值。但不允许为本规范定义的函数添加可选参数。

符合性实现允许接受额外的值,并可针对下述 options 参数的属性采用实现自定义行为,而不是抛出 RangeError

3 规范性引用

下列引用文件是本文件应用所必需的。对于标明日期的引用,仅适用所引版本。对于未标明日期的引用,适用被引用文件的最新版本(包括任何修订)。

ECMAScript 2026 语言规范(ECMA-262 第17,或后续版本)。
https://www.ecma-international.org/publications/standards/Ecma-262.htm

本规范依赖上述参考资料的章节会尽力保持更新,但不能保证与这些标准完全同步。

4 概述

本节为非规范性内容。

4.1 国际化、本地化与全球化

软件的国际化指的是设计软件,使其能够支持或易于适应不同语言用户和不同文化期待的需求,并能够实现全球范围的交流。本地化则是将软件实际适配到某种特定语言和文化。软件全球化通常被理解为国际化和本地化的结合。全球化的基础是采用支持所有语言的文本表示,并使用标准标识符来识别语言、国家、时区及其他相关参数。接下来是采用用户能理解的界面语言和数据展示,最终还常常需要针对用户的语言、文化和环境进行产品特定的适配。

ECMA-262通过采用 Unicode 进行文本表示并提供少量语言敏感函数,为国际化奠定了基础,但这些函数的行为应用几乎无法控制。本规范在此基础之上,提供了一套可定制的语言敏感功能。该 API 对于未国际化的应用也很有用,因为即使只针对一种语言和地区的应用,也需要正确支持该语言和地区。当然,API 也支持需要同时支持多语言和多地区的应用,比如服务器环境下。

4.2 API 概述

本规范旨在通过提供关键语言敏感功能来补充 ECMA-262,可以整体或部分集成到其实现中。本规范引入了 ECMAScript 代码可观察到的新语言值(如 [[FallbackSymbol]] 内部槽的值,以及通过 %Intl% 使用 属性访问可递归获取的值集),并且细化了ECMA-262中部分函数的定义(详见下文)。这两类内容都不限制 ECMA-262已定义的值和接口的允许行为,以便任何实现都能采用本规范。

本规范提供了绝大多数应用所需的若干关键语言敏感功能:语言环境选择与检测、字符串比较(排序规则)与大小写转换、复数规则、文本分割、数字、绝对和相对日期与时间、时长与列表的格式化。虽然 ECMA-262为这些基本功能提供了对应函数(Array.prototypetoLocaleStringString.prototypelocaleComparetoLocaleLowerCasetoLocaleUpperCaseNumber.prototypetoLocaleStringDate.prototypetoLocaleStringtoLocaleDateStringtoLocaleTimeString),但其具体行为很大程度上是实现自定义的。本规范提供了更多功能、语言及行为细节的控制,并对所需功能做了更完整的规范化描述。

应用可以通过两种方式使用 API:

  1. 直接使用:通过服务构造函数构造对象,指定优先语言列表和配置选项。该对象提供主功能(如compareselectformat等),可多次调用。同时还提供resolvedOptions函数,应用可用于查询对象的具体配置。
  2. 间接使用:通过上述 ECMA-262 的函数。排序和格式化函数在本规范中重新定义,以接受与 Collator、NumberFormat 和 DateTimeFormat 构造函数相同的参数,并生成与它们的 compare 或 format 方法一致的结果。大小写转换函数也被重新定义为可接受优先语言列表。

Intl 对象用于打包本规范定义的所有功能,以避免命名冲突。

本 API 虽然包含多种格式化器,但不提供任何解析能力。这是有意为之,经过充分讨论,最终在权衡各种利弊后做出决定。详情可见议题讨论

4.3 API 约定

每个 Intl 构造函数都应表现为类定义,作为函数调用(未指定 NewTarget)时抛出 TypeError 异常。为兼容以往版本,这一约定不适用于 %Intl.Collator%%Intl.DateTimeFormat%%Intl.NumberFormat%,它们作为函数调用时会构造并返回新对象。

在 ECMA 402 v1 中,Intl 构造函数支持一种模式,即以已有对象作为接收者调用时,会向该对象添加相关内部槽,从而将其转变为类实例。ECMA 402 v2 为避免向现有对象添加内部槽,移除了此能力。ECMA 402 v3 又以“规范性可选”方式重新引入了此能力,即在构造函数被调用时,可将底层 Intl 实例链到任意对象上。详见议题57

4.4 实现依赖

由于国际化的特殊性,本规范必须允许部分细节由实现决定:

  • 实现支持且具备充分本地化的语言环境集合: 语言学家记录了数千种人类语言,IANA 语言 子标签注册表包含7000多个主语言子标签(作为语言环境标识符基础)。即使是大型语言环境数据集(如 CLDR),也只覆盖了极少数语言及其地区或方言变体。定位于资源受限设备的实现还可能进一步缩减支持范围。
  • 本地化格式(如格式模式)的具体形式:许多情况下,依赖语言环境的约定并未标准化,因而不同形式可能并存,或随时间变化。不同国际化库可能实现了不同形式,但没有哪种是错误的。为支持基于现有库实现本 API,必须允许此类差异。
  • Unicode 的子集:某些操作(如排序规则)针对可能包含整个 Unicode 字符集字符的字符串。然而,无论 Unicode 标准还是 ECMAScript 标准,都允许实现只支持 Unicode 的子集。此外,语言环境约定通常并不规定整个字符集的行为,而只针对相关字符。虽然 Unicode 排序算法结合了整个字符集的默认排序顺序和本地定制能力,子集和定制仍会导致行为差异。

在浏览器实现中,特定来源可见的初始语言环境、货币、日历、编号系统及其他可枚举项集合,必须在所有使用相同用户 代理字符串(引擎和平台版本)的用户间保持一致。此外,这些集合的动态变化不得导致用户间可区分。此约束旨在降低国际化相关的指纹识别风险,未来版本可能会放宽。受此约束影响,允许按需安装语言环境的浏览器实现首次处理来自某来源、可能需要安装新语言环境的请求时,不能透露该语言环境是否已安装。

在本规范中,实现及语言环境相关行为称为 ILD,实现、语言环境及编号系统相关行为称为 ILND

4.4.1 各实现间的兼容性

ECMA 402 描述了其函数所用数据的结构。数据内容由实现决定,并会随时间变化、各实现间不同。程序员可以观察到这些差异,并可编写依赖特定输出的程序。然而,本规范试图描述合理约束,以便优秀的程序能在不同实现间正常运行。鼓励各实现继续协作,推动语言数据的统一。

5 记号约定

本标准采用了 ECMA-262 的部分记号约定:

ECMA-262 所述,算法用于精确定义 ECMAScript 构造的语义要求,但并不意味着必须采用任何特定的实现技术。内部槽用于定义对象值的语义,但不是 API 的一部分,仅为说明目的而设。API 的实现必须表现得如同按照这里描述的方式创建和操作内部槽。

作为 Record 规范类型的扩展,记号“[[<name>]]”表示其名字由变量 name 给定的字段,name 必须为字符串值。例如,若变量 s 的值为 "a",则 [[<s>]] 表示字段 [[a]]

本规范使用 规范性可选 标记的区块来表示 ECMA 262 中 附录 B 的含义。即,当 ECMAScript 宿主为网页浏览器时,规范性可选部分为必需;若 ECMAScript 宿主不是网页浏览器,则该部分内容为规范性但可选。

5.1 知名内在对象

下表扩展了 知名内在对象表。

表 1:知名内在对象(扩展部分)
内在名 全局名 ECMAScript 语言关联
%Intl% Intl Intl 对象 (8)
%Intl.Collator% Intl.Collator Intl.Collator 构造函数 (10.1)
%Intl.DateTimeFormat% Intl.DateTimeFormat Intl.DateTimeFormat 构造函数 (11.1)
%Intl.DisplayNames% Intl.DisplayNames Intl.DisplayNames 构造函数 (12.1)
%Intl.DurationFormat% Intl.DurationFormat Intl.DurationFormat 构造函数 (13.1)
%Intl.ListFormat% Intl.ListFormat Intl.ListFormat 构造函数 (14.1)
%Intl.Locale% Intl.Locale Intl.Locale 构造函数 (15.1)
%Intl.NumberFormat% Intl.NumberFormat Intl.NumberFormat 构造函数 (16.1)
%Intl.PluralRules% Intl.PluralRules Intl.PluralRules 构造函数 (17.1)
%Intl.RelativeTimeFormat% Intl.RelativeTimeFormat Intl.RelativeTimeFormat 构造函数 (18.1)
%Intl.Segmenter% Intl.Segmenter Intl.Segmenter 构造函数 (19.1)
%IntlSegmentIteratorPrototype% Segment Iterator 对象的原型 (19.6.2)
%IntlSegmentsPrototype% Segments 对象的原型 (19.5.2)

6 语言环境、货币、时区、计量单位、编号系统、排序规则与日历的标识

本条款说明本规范中用于标识语言环境、货币、时区、计量单位、编号系统、排序规则、日历以及模式字符串的字符串值。

6.1 大小写敏感性与大小写映射

用于标识语言环境、货币、文字体系(script)和时区的字符串值以 ASCII 忽略大小写的方式进行解释:将 0x0041 到 0x005A(对应 Unicode 字符 LATIN CAPITAL LETTER A 到 LATIN CAPITAL LETTER Z)视为与对应的 0x0061 到 0x007A(对应 Unicode 字符 LATIN SMALL LETTER A 到 LATIN SMALL LETTER Z)等价(均包含端点)。不适用任何其他大小写折叠等价关系。

例如,"ß"(U+00DF)不得与 "SS"(U+0053、U+0053)匹配或映射。"ı"(U+0131)不得与 "I"(U+0049)匹配或映射。

字符串值 SASCII-uppercase是将 S 中每个 ASCII 小写字母码元(0x0061 至 0x007A,含端点)替换为对应的 ASCII 大写字母码元(0x0041 至 0x005A,含端点)且保留所有其他码元后得到的字符串值。

字符串值 SASCII-lowercase是将 S 中每个 ASCII 大写字母码元(0x0041 至 0x005A,含端点)替换为对应的 ASCII 小写字母码元(0x0061 至 0x007A,含端点)且保留所有其他码元后得到的字符串值。

A 的 ASCII-uppercase 与 B 的 ASCII-uppercase 完全相同(码元序列相同),则字符串值 A 与字符串值 BASCII-case-insensitive match。若 BCodePointsToString(A) 是 ASCII-case-insensitive match,则 Unicode 码点序列 AB 是 ASCII-case-insensitive match。

6.2 语言标签

本规范使用由 Unicode 技术标准 #35 第一部分 核心,第 3.3 节 BCP 47 一致性 定义的Unicode BCP 47 语言环境标识符来标识语言环境,其算法引用了 第 3 节 Unicode 语言与语言环境标识符 语法中定义的Unicode 语言环境非终结符。 每个此类标识符也可称为语言标签,且事实上作为 BCP 47 中术语所用的语言标签是有效的。 按 Unicode 技术标准 #35 第一部分 核心,第 3.2.1 节 Canonical Unicode Locale Identifiers 指定的规范形式的语言环境标识符称为“Unicode 规范化语言环境标识符”。

语言环境标识符由大小写不敏感的 Unicode 基本拉丁字母数字子标签组成,子标签之间用字符 "-"(U+002D HYPHEN-MINUS)分隔,其中单字符的 子标签称为“单例子标签”。Unicode 技术标准 #35 第一部分 核心,第 3.6 节 Unicode BCP 47 U 扩展子标签序列被广泛使用,术语“Unicode 语言环境扩展序列”用于描述可由 Unicode 语言环境非终结符 unicode_locale_extensions 匹配、且不属于 "-x-…" 私有用法子标签序列的语言标签最长子串。它以 "-u-" 开始,并包含紧随其后的所有非单例子标签及其之前的 "-" 分隔符。例如,Unicode 语言环境扩展序列"en-US-u-fw-mon-x-u-ex-foobar" 中为 "-u-fw-mon"

所有结构上有效的语言标签均可用于本规范定义的 API,但实现并不要求使用 Unicode 通用语言环境数据存储库(CLDR)数据进行校验;实现具备充分本地化支持的语言环境集合(因而语言标签集合)为实现自定义Intl 构造函数会将请求的语言标签映射至各自实现所支持的语言环境。

6.2.1 IsStructurallyValidLanguageTag ( locale )

抽象操作 IsStructurallyValidLanguageTag 接受参数 locale(字符串)并返回布尔值。其用于判定 locale 是否为语法上格式良好的语言标签。它不考虑 locale 是否传达任何有意义的语义,也不区分别名子标签与其首选替代子标签,亦不要求规范化大小写或 子标签排序。调用时执行下列步骤:

  1. lowerLocalelocaleASCII-lowercase
  2. lowerLocale 无法被 unicode_locale_id Unicode 语言环境非终结符匹配,则返回 false
  3. lowerLocale 使用了 Unicode 技术标准 #35 第一部分 核心,第 3.3 节 BCP 47 一致性 中描述的任何向后兼容语法,则返回 false
  4. baseNameGetLocaleBaseName(lowerLocale)。
  5. variantsGetLocaleVariants(baseName)。
  6. variants 不为 undefined,则
    1. variants 含有任何重复的 子标签,返回 false
  7. extensionslowerLocalebaseName 之后的后缀。
  8. 注意:匹配 pu_extensions Unicode 语言环境非终结符"-x-…" 私有用法 子标签序列必须被忽略,但位于末尾且无后续内容的独立 "x" 子标签不影响以下检查。
  9. puIndexStringIndexOf(extensions, "-x-", 0)。
  10. puIndexnot-found,则将 extensions 设为 extensions 从 0 至 puIndex子串
  11. extensions 非空字符串,则
    1. extensions 含有任何重复的 单例子标签,返回 false
    2. transformExtensionextensions 的最长子串,该子串可被 transformed_extensions Unicode 语言环境非终结符匹配。若不存在此子串,返回 true
    3. 断言transformExtension 从 0 至 3 的 子串"-t-"
    4. tPrefixtransformExtension 自索引 3 起的 子串
    5. tlangtPrefix 的最长前缀,可被 tlang Unicode 语言环境非终结符匹配。若不存在此前缀,返回 true
    6. tlangVariantsGetLocaleVariants(tlang)。
    7. tlangVariants 含有任何重复的 子标签,返回 false
  12. 返回 true

6.2.2 CanonicalizeUnicodeLocaleId ( locale )

抽象操作 CanonicalizeUnicodeLocaleId 接受参数 locale语言标签)并返回一个Unicode 规范化语言环境标识符。它返回 locale 的规范且大小写规整后的形式。调用时执行以下步骤:

  1. localeId 为按照 Unicode 技术标准 #35 第一部分 核心,附录 C LocaleId Canonicalizationlocale 转换为规范形式后得到的字符串值(注意该算法从仅语法规范化开始)。
  2. localeId 包含一个子串,该子串是一个Unicode 语言环境扩展序列,则
    1. extensionlocaleId 中该 Unicode 语言环境扩展序列子串所组成的字符串值。
    2. newExtension"-u"
    3. componentsUnicodeExtensionComponents(extension)。
    4. components.[[Attributes]] 中的每个元素 attr,执行:
      1. newExtension 设为 newExtension"-"attr字符串连接
    5. components.[[Keywords]] 中的每个 Record { [[Key]], [[Value]] } keyword,执行:
      1. newExtension 设为 newExtension"-"keyword.[[Key]]字符串连接
      2. keyword.[[Value]] 非空字符串,则
        1. newExtension 设为 newExtension"-"keyword.[[Value]]字符串连接
    6. 断言newExtension 不等于 "-u"
    7. localeId 设为 localeId 的一个副本,其中首次出现的子串 extension 已被 newExtension 替换。
  3. 返回 localeId
步骤 2 确保返回的语言标签中的Unicode 语言环境扩展序列包含:
  • 对于输入中重复的任何 attribute,仅包含第一次出现;
  • 对于给定 key 的 keyword,仅包含输入中的第一个。

6.2.3 DefaultLocale ( )

实现自定义的抽象操作 DefaultLocale 不带参数,返回一个Unicode 规范化语言环境标识符。返回的字符串值表示结构上有效(6.2.1)规范化(6.2.2)语言标签,用于表示宿主环境当前的语言环境。它不得包含Unicode 语言环境扩展序列

返回值可能成为指纹识别向量。在浏览器环境中,应与 navigator.language 一致,以避免提供额外的区分信息。

6.3 货币代码

本规范使用 ISO 4217 定义的 3 字母货币代码来标识货币。其规范形式为大写。

所有格式良好的 3 字母 ISO 4217 货币代码均被允许。但实现为哪些“货币代码 + 语言标签”的组合提供本地化货币符号是实现相关的。若无可用的本地化货币符号,则在格式化时使用 ISO 4217 货币代码。

6.3.1 IsWellFormedCurrencyCode ( currency )

抽象操作 IsWellFormedCurrencyCode 接受参数 currency(字符串)并返回布尔值。它验证参数 currency 是否表示一个格式良好的 3 字母 ISO 4217 货币代码。调用时执行以下步骤:

  1. currency 的长度不为 3,返回 false
  2. normalizedcurrencyASCII-uppercase
  3. normalized 含有 0x0041 至 0x005A(对应 Unicode 字符 LATIN CAPITAL LETTER A 至 LATIN CAPITAL LETTER Z)之外的任何码元,返回 false
  4. 返回 true

6.4 AvailableCanonicalCurrencies ( )

实现自定义的抽象操作 AvailableCanonicalCurrencies 不带参数并返回一个字符串的List。返回的List按照字典序码元顺序排序,且包含唯一、格式良好且大写规范化的 3 字母 ISO 4217 货币代码,标识实现为其提供 Intl.DisplayNames 与 Intl.NumberFormat 对象功能支持的货币。

6.5 IANA 时区数据库的使用

采用本规范的实现必须具备时区感知能力:必须使用 IANA 时区数据库 https://www.iana.org/time-zones/ 来提供可用的命名时区标识符以及 ECMAScript 计算和格式化所使用的数据。 本节定义具备时区感知的实现应如何使用 IANA 时区数据库。 若某字符串不是 IANA 时区数据库中的 Zone 名称或 Link 名称,则不得作为可用的命名时区标识符。 ECMAScript 内建对象返回的可用的命名时区标识符必须使用 IANA 时区数据库中的大小写形式。

IANA 时区数据库中的每个 Zone 必须为主时区标识符,每个 Link 名称必须为非主时区标识符,并解析为其对应的 Zone 名称,但以下在 AvailableNamedTimeZoneIdentifiers 中实现的例外情况除外:

  • 出于历史原因,"UTC"必须为主时区标识符"Etc/UTC""Etc/GMT""GMT",以及解析到上述任一者的所有 Link 名称,必须为解析至 "UTC" 的非主时区标识符。
  • 文件 zone.tab 中 “TZ” 列出现的任何 Link 名称必须为主时区标识符。 例如,"Europe/Prague""Europe/Bratislava" 都必须是主时区标识符。 此要求保证每个 ISO 3166-1 Alpha-2 国家代码至少拥有一个主时区标识符,并确保未来某一国家的时区规则变更不会影响使用另一国家时区的 ECMAScript 程序,除非这些国家的领土边界也发生变化。
  • 任何未列于文件 zone.tab “TZ” 列、且代表的地理区域完全位于单一 ISO 3166-1 Alpha-2 国家代码领土内的 Link 名称,必须解析到一个同样代表完全位于该国家代码领土内的主标识符。 例如,"Atlantic/Jan_Mayen" 必须解析到 "Arctic/Longyearbyen"

IANA 时区数据库提供的构建选项会影响哪些可用的命名时区标识符是主标识符。 默认构建选项会合并不同国家的时区,例如 "Atlantic/Reykjavik" 会构建为指向 Zone "Africa/Abidjan" 的 Link。 在 IANA 时区数据库的未来版本中,地理与政治上不同的地区很可能引入分歧的时区规则。 上述例外有助于缓解这些未来兼容性问题。

Unicode 通用语言环境数据存储库(CLDR)在判定哪些可用的命名时区标识符是主或非主时,实施了上述大多数例外。 虽然建议使用 CLDR 数据以提升各实现之间的一致性,但并非强制。 非基于 CLDR 的实现仍可使用 CLDR 在 timezone.xml 中的标识符数据。 实现也可以直接构建 IANA 时区数据库,例如使用 PACKRATDATA=backzone PACKRATLIST=zone.tab 等构建选项,并进行任何必要的后处理以确保符合上述要求。

IANA 时区数据库通常每年更新 5 至 10 次。 这些更新可能新增 Zone 或 Link 名称,可能将 Zone 改为 Link,也可能更改与任何 Zone 关联的 UTC 偏移与转换。 建议实现尽快包含对 IANA 时区数据库的更新。 如此可以确保 ECMAScript 程序准确执行与时区相关的计算,并可使用由外部输入或宿主环境提供的新添加的可用的命名时区标识符

尽管 IANA 时区数据库维护者力求稳定,但在少数情况下(平均每年少于一次)某个 Zone 可能被新 Zone 替代。 例如,2022 年 "Europe/Kiev" 被弃用为解析到新 "Europe/Kyiv" Zone 的 Link。 被弃用的 Link 称为重命名时区标识符,新添加的 Zone 称为替代时区标识符

为减少这些不频繁变更带来的影响,实现最初应将每个替代时区标识符添加为解析到现有重命名时区标识符的非主时区标识符。 这既允许 ECMAScript 程序识别两个标识符,也降低了将替代时区标识符发送到尚未识别它的其他系统的可能性。 经过一个重命名等待期后,实现应将新 Zone 提升为主时区标识符,同时将重命名时区标识符降级为非主。 为给其他系统提供充足的更新时间,建议的重命名等待期为两年。 然而,这无需精确或动态。 相反,实现应在等待期结束后,作为更新时区数据的常规发布流程的一部分,将替代时区标识符设为主标识符。

等待期仅应在新增的 Zone 用于替换现有 Zone 时适用。 若仅是现有的 Zone 与 Link 互换位置,则不视为重命名,无需等待期。

若实现会在某个agent的生命周期内修订时区信息,则要求该agent先前观察到的结果与以下内容保持一致:可用的命名时区标识符列表;与任何可用的命名时区标识符相关联的主时区标识符;以及与任何可用的命名时区标识符相关联的 UTC 偏移与转换。 鉴于支持该要求的复杂性,建议实现为每个agent在其生命周期内维持 IANA 时区数据库的完全一致副本。

本节作为补充,但不取代21.4.1.19

6.5.1 AvailableNamedTimeZoneIdentifiers ( )

实现自定义的抽象操作 AvailableNamedTimeZoneIdentifiers 不带参数,返回一个List,其中元素为Time Zone Identifier Record。 其结果描述了本实现中的所有可用的命名时区标识符,以及对应于每个可用的命名时区标识符主时区标识符。 该List按照每个Time Zone Identifier Record[[Identifier]] 字段排序。

此定义取代了21.4.1.23中的定义。

  1. identifiers 为一个List,包含 IANA 时区数据库中每个 Zone 或 Link 名称的字符串值。
  2. 断言identifiers 的任一元素都不是另一个元素的ASCII-case-insensitive match
  3. 按照字典序码元顺序identifiers 排序。
  4. result 为一个新的空List
  5. identifiers 中的每个元素 identifier,执行:
    1. primaryidentifier
    2. identifier 是 IANA 时区数据库中的 Link 名称,且未出现在 IANA 时区数据库的 zone.tab 文件 “TZ” 列中,则
      1. zone 为根据 IANA 时区数据库解析 Link 名称规则,identifier 解析到的 Zone 名称。
      2. zone"Etc/" 开头,则
        1. primary 设为 zone
      3. 否则,
        1. identifierCountryCode 为其对应地理区域包含 identifierISO 3166-1 Alpha-2 国家代码。
        2. zoneCountryCode 为其对应地理区域包含 zone 的 ISO 3166-1 Alpha-2 国家代码。
        3. identifierCountryCode 等于 zoneCountryCode,则
          1. primary 设为 zone
        4. 否则,
          1. countryCodeLineCount 为 IANA 时区数据库文件 zone.tab 中 “country-code” 列等于 identifierCountryCode 的行数。
          2. countryCodeLineCount 为 1,则
            1. countryCodeLine 为 IANA 时区数据库文件 zone.tab 中 “country-code” 列等于 identifierCountryCode 的那一行。
            2. primary 设为 countryCodeLine 的 “TZ” 列内容。
          3. 否则,
            1. backzoneundefined
            2. backzoneLinkLines 为 IANA 时区数据库文件 backzone 中,以 "Link ""#PACKRATLIST zone.tab Link " 开头的行所组成的List
            3. backzoneLinkLines 中的每个元素 line,执行:
              1. iStringIndexOf(line, "Link ", 0)。
              2. line 设为 linei + 5 起的 子串
              3. backzoneAndLinkStringSplitToList(line, " ")。
              4. 断言backzoneAndLink 至少有两个元素,且 backzoneAndLink[0] 与 backzoneAndLink[1] 均为可用的命名时区标识符
              5. backzoneAndLink[1] 等于 identifier,则
                1. 断言backzoneundefined
                2. backzone 设为 backzoneAndLink[0]。
            4. 断言backzone 不为 undefined
            5. primary 设为 backzone
    3. primary 属于 "Etc/UTC""Etc/GMT""GMT" 中之一,则将 primary 设为 "UTC"
    4. primary 是一个替代时区标识符,且其重命名等待期尚未结束,则
      1. renamedIdentifierprimary 所替代的重命名时区标识符
      2. primary 设为 renamedIdentifier
    5. recordTime Zone Identifier Record { [[Identifier]]: identifier, [[PrimaryIdentifier]]: primary }。
    6. record 追加至 result
  6. 断言result 包含某个Time Zone Identifier Record r,满足 r.[[Identifier]]"UTC"r.[[PrimaryIdentifier]]"UTC"
  7. 返回 result
注 1

上述将 Link 解析为主时区标识符的算法,旨在与 Unicode 国际化组件(ICU)中的 icu::TimeZone::getIanaID() 行为,以及 Unicode 通用语言环境数据存储库(CLDR)中维护时区标识符数据的流程相对应。

该算法在不跨越 ISO 3166-1 Alpha-2 国家代码边界的前提下,使用 IANA 时区数据库中的 zone.tabbackzone 数据,将 Link 解析为主时区标识符。 如果某 Link 的国家代码在 zone.tab 中仅有一行,则该行决定对应的主时区标识符。 若该国家代码在 zone.tab 中有多行,则必须使用 backzone 中的历史映射来确定正确的主时区标识符

例如,若要解析 "Pacific/Truk"(国家代码 "FM"),而 IANA 时区数据库的默认构建选项将其标识为指向 "Pacific/Port_Moresby"(国家代码 "PG")的 Link,则需在 zone.tab 的 “country-code” 列中查找与 "FM" 对应的行。 若仅有一行,则该行的 “TZ” 列决定与 "Pacific/Truk" 关联的主时区标识符。 但若 zone.tab 中有多条 "FM" 行,则必须检查 backzone,类似 "Link Pacific/Chuuk Pacific/Truk" 的行将导致使用 "Pacific/Chuuk" 作为主时区标识符

注意,zone.tab 是首选的映射数据来源,因为 backzone 的映射在极少数情况下可能跨越 ISO 3166-1 Alpha-2 国家代码边界。 例如,"Atlantic/Jan_Mayen"(国家代码 "SJ")在 backzone 中被映射到 "Europe/Oslo"(国家代码 "NO")。 截至 IANA 时区数据库 2024a 版本,这是唯一发生此情况的例子。

注 2
IANA 时区数据库中的时区标识符可能随时间变化。 至少建议实现将对 AvailableNamedTimeZoneIdentifiers 结果的更改限制为GetAvailableNamedTimeZoneIdentifier外围 agent生命周期内允许的更改。 鉴于支持这些建议的复杂性,建议 AvailableNamedTimeZoneIdentifiers(因此 GetAvailableNamedTimeZoneIdentifier 的结果)在外围 agent生命周期内保持不变。

6.5.2 GetAvailableNamedTimeZoneIdentifier ( timeZoneIdentifier )

抽象操作 GetAvailableNamedTimeZoneIdentifier 接受参数 timeZoneIdentifier(字符串),返回Time Zone Identifier Recordempty。 若 timeZoneIdentifier可用的命名时区标识符,则返回由 Records之一组成的元素,该元素来自List,该 ListAvailableNamedTimeZoneIdentifiers 返回。 否则,返回 empty。 调用时执行以下步骤:

  1. AvailableNamedTimeZoneIdentifiers() 的每个元素 record,执行:
    1. record.[[Identifier]]timeZoneIdentifierASCII-case-insensitive match,则返回 record
  2. 返回 empty
对于任意 timeZoneIdentifier,或任何与其ASCII-case-insensitive match 的值,要求在外围 agent生命周期内,所返回的Time Zone Identifier Record字段值保持相同。 进一步要求在外围 agent生命周期内,时区标识符不得从主标识符动态变为非主;亦即,若 timeZoneIdentifier 与先前一次调用结果的 [[PrimaryIdentifier]] 字段为ASCII-case-insensitive match,则 GetAvailableNamedTimeZoneIdentifier(timeZoneIdentifier) 必须返回 [[Identifier]] 等于 [[PrimaryIdentifier]]Time Zone Identifier Record。 鉴于支持这些要求的复杂性,建议 AvailableNamedTimeZoneIdentifiers 的结果(因此 GetAvailableNamedTimeZoneIdentifier 的结果)在外围 agent生命周期内保持不变。

6.5.3 AvailablePrimaryTimeZoneIdentifiers ( )

抽象操作 AvailablePrimaryTimeZoneIdentifiers 不带参数,返回一个字符串的List。 返回的List是按序排列的 IANA 时区数据库中受支持的 Zone 与 Link 名称的List。调用时执行:

  1. recordsAvailableNamedTimeZoneIdentifiers()。
  2. result 为一个新的空List
  3. records 中的每个元素 timeZoneIdentifierRecord,执行:
    1. timeZoneIdentifierRecord.[[Identifier]] 等于 timeZoneIdentifierRecord.[[PrimaryIdentifier]],则
      1. timeZoneIdentifierRecord.[[Identifier]] 追加至 result
  4. 返回 result

6.5.4 StringSplitToList ( S, separator )

抽象操作 StringSplitToList 接受参数 S(字符串)与 separator(字符串),返回一个字符串的List。 返回的List包含 S 的所有两两不相交的子串,这些子串不包含 separator,但紧接着在其前后出现 separator。 在相邻的 separator 之间、S 起始处的 separator 之前、或 S 末尾处的 separator 之后,每个这样的子串都将是空字符串;其余情况下不为空。 调用时执行以下步骤:

  1. 断言S 不是空字符串。
  2. 断言separator 不是空字符串。
  3. separatorLengthseparator 的长度。
  4. substrings 为一个新的空List
  5. i 为 0。
  6. jStringIndexOf(S, separator, 0)。
  7. j 不为 not-found 时重复:
    1. TSij子串
    2. T 追加至 substrings
    3. i 设为 j + separatorLength
    4. j 设为 StringIndexOf(S, separator, i)。
  8. TSi 起的 子串
  9. T 追加至 substrings
  10. 返回 substrings

6.6 计量单位标识符

本规范使用由 Unicode 技术标准 #35 第二部分 通用,第 6.2 节 单位标识符 定义的核心单位标识符(或等价的 core unit ID)来标识计量单位。其规范形式为仅包含 Unicode 基本拉丁小写字母(U+0061 LATIN SMALL LETTER A 至 U+007A LATIN SMALL LETTER Z)以及零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

仅有限集合的核心单位标识符被认可。 使用未认可的核心单位标识符会导致抛出 RangeError

6.6.1 IsWellFormedUnitIdentifier ( unitIdentifier )

抽象操作 IsWellFormedUnitIdentifier 接受参数 unitIdentifier(字符串)并返回布尔值。它验证参数 unitIdentifier 是否表示一个格式良好的核心单位标识符,且该标识符要么是被认可的单一单位,要么是由两个被认可的单一单位通过除法构成的复合单位。调用时执行以下步骤:

  1. IsSanctionedSingleUnitIdentifier(unitIdentifier) 为 true,则
    1. 返回 true
  2. iStringIndexOf(unitIdentifier, "-per-", 0)。
  3. inot-foundStringIndexOf(unitIdentifier, "-per-", i + 1) 非 not-found,则
    1. 返回 false
  4. 断言:五字符子串 "-per-"unitIdentifier 中恰好出现一次,位置为索引 i
  5. numeratorunitIdentifier 从 0 到 i子串
  6. denominatorunitIdentifieri + 5 起的 子串
  7. IsSanctionedSingleUnitIdentifier(numerator) 与 IsSanctionedSingleUnitIdentifier(denominator) 均为 true,则
    1. 返回 true
  8. 返回 false

6.6.2 IsSanctionedSingleUnitIdentifier ( unitIdentifier )

抽象操作 IsSanctionedSingleUnitIdentifier 接受参数 unitIdentifier(字符串)并返回布尔值。它验证参数 unitIdentifier 是否属于本规范当前版本认可的单一单位标识符,该集合是 CLDR(通用语言环境数据存储库)第 38 版单位有效性数据 的子集;该列表可能随时间增长。正如 Unicode 技术标准 #35 第二部分 通用,第 6.2 节 单位标识符 所述,单一单位标识符是未由其他单位标识符的乘除构成的核心单位标识符。调用时执行:

  1. unitIdentifier 列于下方表 2,返回 true
  2. 否则,返回 false
表 2:ECMAScript 允许使用的单一单位
单一单位标识符
acre
bit
byte
celsius
centimeter
day
degree
fahrenheit
fluid-ounce
foot
gallon
gigabit
gigabyte
gram
hectare
hour
inch
kilobit
kilobyte
kilogram
kilometer
liter
megabit
megabyte
meter
microsecond
mile
mile-scandinavian
milliliter
millimeter
millisecond
minute
month
nanosecond
ounce
percent
petabyte
pound
second
stone
terabit
terabyte
week
yard
year

6.6.3 AvailableCanonicalUnits ( )

抽象操作 AvailableCanonicalUnits 不带参数,返回一个字符串的List。 返回的List按照字典序码元顺序排序,由表 2每一行(除表头)列出的简单单位标识符的唯一值构成。

6.7 编号系统标识符

本规范使用与 Unicode 技术标准 #35 第三部分 数字,第 1 节 编号系统中引用的名称相对应的编号系统标识符来标识编号系统。其规范形式为仅包含 Unicode 基本拉丁小写字母(U+0061 LATIN SMALL LETTER A 至 U+007A LATIN SMALL LETTER Z)的字符串。

6.7.1 AvailableCanonicalNumberingSystems ( )

实现自定义的抽象操作 AvailableCanonicalNumberingSystems 不带参数,返回一个字符串的List。 返回的List按照字典序码元顺序排序,包含唯一的、规范的编号系统标识符,这些标识符对应实现为其提供 Intl.DateTimeFormat、Intl.NumberFormat 与 Intl.RelativeTimeFormat 对象功能支持的编号系统。 该List必须包含表 28每一行(除表头)的 Numbering System 值。

6.8 排序规则类型

本规范使用由 Unicode 技术标准 #35 第五部分 排序,第 3.1 节 排序类型 定义的排序规则类型来标识排序规则。其规范形式为仅包含 Unicode 基本拉丁小写字母(U+0061 LATIN SMALL LETTER A 至 U+007A LATIN SMALL LETTER Z)以及零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

6.8.1 AvailableCanonicalCollations ( )

实现自定义的抽象操作 AvailableCanonicalCollations 不带参数,返回一个字符串的List。 返回的List按照字典序码元顺序排序,且包含唯一的、规范的排序规则类型,用于标识实现为其提供 Intl.Collator 对象功能支持的排序规则。

6.9 日历类型

本规范使用由 Unicode 技术标准 #35 第四部分 日期,第 2 节 日历元素 定义的日历类型来标识日历。其规范形式为仅包含 Unicode 基本拉丁小写字母(U+0061 LATIN SMALL LETTER A 至 U+007A LATIN SMALL LETTER Z)以及零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

6.9.1 AvailableCalendars ( )

实现自定义的抽象操作 AvailableCalendars 不带参数,返回一个字符串的List。 返回的List按照字典序码元顺序排序,且包含规范形式(6.9)的唯一日历类型,用于标识实现为其提供 Intl.DateTimeFormat 对象功能支持的日历,包括它们的别名(例如 "islamicc""islamic-civil" 要么同时包含,要么同时不包含)。该List必须包含 "iso8601"

6.10 模式字符串类型

模式字符串(Pattern String)一种字符串值,它包含零个或多个形如 "{key}" 的子串,其中 key 可以是仅由ASCII 单词字符构成的任意非空序列。抽象模式字符串的语法属于实现细节,不向 ECMA-402 的用户暴露。

7 ECMAScript 标准内建对象的要求

除非本文件另有规定,本标准中描述的对象、函数和 构造函数,均需遵循 ECMAScript 标准内建对象所指定的通用要求和限制。

8 Intl 对象

Intl 对象

8.1 Intl 对象的值属性

8.1.1 Intl [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl"

此属性具有如下特性:{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

8.2 Intl 对象的构造函数属性

除 Intl.Locale 外,下列每个 构造函数都是创建提供语言环境相关服务对象的服务构造函数

8.2.1 Intl.Collator ( . . . )

10

8.2.2 Intl.DateTimeFormat ( . . . )

11

8.2.3 Intl.DisplayNames ( . . . )

12

8.2.4 Intl.DurationFormat ( . . . )

13

8.2.5 Intl.ListFormat ( . . . )

14

8.2.6 Intl.Locale ( . . . )

15

8.2.7 Intl.NumberFormat ( . . . )

16

8.2.8 Intl.PluralRules ( . . . )

17

8.2.9 Intl.RelativeTimeFormat ( . . . )

18

8.2.10 Intl.Segmenter ( . . . )

19

8.3 Intl 对象的函数属性

8.3.1 Intl.getCanonicalLocales ( locales )

当以参数 locales 调用 getCanonicalLocales 方法时,执行以下步骤:

  1. ll 为 ? CanonicalizeLocaleList(locales)。
  2. 返回 CreateArrayFromList(ll)。

8.3.2 Intl.supportedValuesOf ( key )

当以参数 key 调用 supportedValuesOf 方法时,执行以下步骤:

  1. key 为 ? ToString(key)。
  2. key"calendar",则
    1. list 为一个新的空List
    2. AvailableCalendars() 的每个元素 identifier,执行:
      1. canonicalCanonicalizeUValue("ca", identifier)。
      2. identifier 等于 canonical,则
        1. identifier 追加至 list
  3. 否则若 key"collation",则
    1. listAvailableCanonicalCollations( )。
  4. 否则若 key"currency",则
    1. listAvailableCanonicalCurrencies( )。
  5. 否则若 key"numberingSystem",则
    1. listAvailableCanonicalNumberingSystems( )。
  6. 否则若 key"timeZone",则
    1. listAvailablePrimaryTimeZoneIdentifiers( )。
  7. 否则若 key"unit",则
    1. listAvailableCanonicalUnits( )。
  8. 否则,
    1. 抛出 RangeError 异常。
  9. 返回 CreateArrayFromList( list )。

9 语言环境与参数协商

服务构造函数使用通用模式,在实现的实际能力与由 localesoptions 参数所表示的请求之间进行协商。此处以描述这些能力的内部槽、使用这些内部槽的抽象操作,以及下文定义的专用数据类型来解释这种通用行为。

可用语言环境列表(Available Locales List)是一个任意顺序且无重复的List,其中每个元素都是语言标签,且每个元素都在结构上有效、已规范化,并且不包含Unicode 语言环境扩展序列。它表示实现于特定上下文中提供功能的全部语言环境。

语言优先级列表(Language Priority List)是一个List,包含结构上有效且已规范化语言标签,按优先级递减表示语言环境偏好序列。它对应于BCP 47RFC 4647 第 2.3 节定义的同名术语,但禁止包含 "*" 元素,并且仅包含已规范化的内容。

解析选项描述符(Resolution Option Descriptor)是一个Record,包含字段 [[Key]](字符串,通常为 [[RelevantExtensionKeys]] List 的元素)与 [[Property]](字符串),以及可选的 [[Type]]booleanstring)和 [[Values]]empty 或一个由ECMAScript 语言值组成的List)。它描述了在对象构造期间如何读取与语言环境解析相关的选项。

9.1 服务构造函数的内部槽

每个服务构造函数都具有以下内部槽:

  • [[AvailableLocales]] 是一个可用语言环境列表。它必须包含DefaultLocale 返回的值。此外,对于每个包含多个子标签的元素,它还必须包含一个同语言子标签且后续子标签为其严格子集(即省略一个或多个)的、更不具体的语言标签,以作为ResolveLocale的潜在回退。特别地,每个同时包含语言子标签、文字(脚本)子标签与地区子标签的元素,必须配有另一个仅包含相同语言子标签与地区子标签、但缺少脚本子标签的元素。例如,
    • 如果 [[AvailableLocales]] 包含 "de-DE",则还必须包含 "de"(它可能被选中以满足诸如 "de-AT""de-CH" 等请求的语言环境)。
    • 如果 [[AvailableLocales]] 包含 "az-Latn-AZ",则还必须包含 "az-AZ"(当 "az-Cyrl" 不可用时,它可能被选中以满足诸如 "az-Cyrl-AZ" 等请求的语言环境)。
  • [[RelevantExtensionKeys]] 是一个List,包含Unicode 技术标准 #35 第一部分 核心,3.6.1 节 键与类型定义中定义且与所构造对象功能相关的Unicode 语言环境扩展序列键。
  • [[ResolutionOptionDescriptors]] 是一个List,其中包含在对象构造期间用于读取选项的解析选项描述符
  • [[SortLocaleData]][[SearchLocaleData]](用于 Intl.Collator)以及 [[LocaleData]](用于其他所有服务构造函数)都是Records。除了其服务构造函数特定的字段外,每个此类Record还为 [[AvailableLocales]] 中包含的每个语言环境设置了一个字段。每个此类以语言环境命名的字段的值是一个Record,其中 [[RelevantExtensionKeys]] 的每个元素标识了一个字段名,该字段的值为非空的List(字符串),表示实现于相关语言环境中对相应Unicode 语言环境扩展序列键所支持的类型值,其中第一个元素为该语言环境中该键的默认值。
例如,一个 DateTimeFormat 的实现可能在其 [[AvailableLocales]] 内部槽中包含语言标签 "fa-IR",并且必须(依据11.2.3)在其 [[RelevantExtensionKeys]] 内部槽中包含键 "ca""hc""nu"。该语言环境的默认日历通常为 "persian",但实现也可能支持 "gregory""islamic""islamic-civil"。因此,DateTimeFormat 的 [[LocaleData]] 内部槽中的Record会包含一个 [[fa-IR]] 字段,其值是一个Record,类似 { [[ca]]: « "persian""gregory""islamic""islamic-civil" », [[hc]]: « … »,[[nu]]: « … » },以及其他以语言环境命名的字段,它们具有相同的值结构但其List中的元素不同。

9.2 抽象操作

9.2.1 CanonicalizeLocaleList ( locales )

抽象操作 CanonicalizeLocaleList 接受参数 locales(一个ECMAScript 语言值),返回一个正常完成,包含语言优先级列表或一个抛出完成。调用时执行以下步骤:

  1. 如果 localesundefined,则
    1. 返回一个新的空List
  2. seen 为一个新的空List
  3. 如果 locales是字符串,或 locales是对象且具有 [[InitializedLocale]] 内部槽,则
    1. OCreateArrayFromListlocales »)。
  4. 否则,
    1. O 为 ? ToObject(locales)。
  5. len 为 ? LengthOfArrayLike(O)。
  6. k 为 0。
  7. k < len 时重复,
    1. Pk 为 ! ToString(𝔽(k))。
    2. kPresent 为 ? HasProperty(O, Pk)。
    3. 如果 kPresenttrue,则
      1. kValue 为 ? Get(O, Pk)。
      2. 如果 kValue不是字符串kValue不是对象,则抛出 TypeError 异常。
      3. 如果 kValue是对象且具有 [[InitializedLocale]] 内部槽,则
        1. tagkValue.[[Locale]]
      4. 否则,
        1. tag 为 ? ToString(kValue)。
      5. 如果 IsStructurallyValidLanguageTag(tag) 为 false,则抛出 RangeError 异常。
      6. canonicalizedTagCanonicalizeUnicodeLocaleId(tag)。
      7. 如果 seen 不包含 canonicalizedTag,则将 canonicalizedTag 追加到 seen
    4. k 设为 k + 1。
  8. 返回 seen
注 1
非规范性摘要:该抽象操作将 locales 参数视为数组,并将其元素复制到一个List中,对元素进行结构上有效的语言标签校验与规范化,并去除重复项。
注 2
要求 kValue 为字符串或对象意味着数值 NaN 不会被解释为语言标签"nan",后者代表闽南语(Min Nan Chinese)。

9.2.2 CanonicalizeUValue ( ukey, uvalue )

抽象操作 CanonicalizeUValue 接受参数 ukey(一个在Unicode 技术标准 #35 第一部分 核心 3.6.1 节 键与类型定义中定义的Unicode 语言环境扩展序列键)与 uvalue(字符串),返回一个字符串。返回的字符串是 ukey 的取值 uvalue 的规范且大小写规整后的形式。调用时执行以下步骤:

  1. lowerValueuvalueASCII-lowercase
  2. canonicalized 为将 lowerValue 作为键 ukey 的取值进行规范化后得到的字符串值,规范化依据 Unicode 技术标准 #35 第一部分 核心,附录 C LocaleId Canonicalization 第 5 节 Canonicalizing Syntax,Processing LocaleIds
  3. 注意:建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的 common/bcp47 中的 'u' 扩展数据。
  4. 返回 canonicalized

9.2.3 LookupMatchingLocaleByPrefix ( availableLocales, requestedLocales )

抽象操作 LookupMatchingLocaleByPrefix 接受参数 availableLocales(一个可用语言环境列表)与 requestedLocales(一个语言优先级列表),返回一个Record,包含字段 [[locale]](一个Unicode 规范化语言环境标识符)与 [[extension]](一个Unicode 语言环境扩展序列empty),或 undefined。它使用BCP 47RFC 4647 第 3.4 节定义的查找(lookup)算法,忽略Unicode 语言环境扩展序列,以确定能满足 requestedLocalesavailableLocales 的最佳元素。若找到非默认的匹配,则返回一个Record,其 [[locale]] 字段包含来自 availableLocales 的匹配语言标签[[extension]] 字段包含 requestedLocales 中对应元素的Unicode 语言环境扩展序列(如果请求的语言标签没有此序列,则为 empty)。调用时执行以下步骤:

  1. 针对 requestedLocales 的每个元素 locale,执行
    1. extensionempty
    2. 如果 locale 包含一个Unicode 语言环境扩展序列,则
      1. extension 设为 locale 的该Unicode 语言环境扩展序列
      2. locale 设为删除所有Unicode 语言环境扩展序列后的字符串值。
    3. prefixlocale
    4. prefix 非空字符串时重复,
      1. 如果 availableLocales 包含 prefix,则返回Record { [[locale]]: prefix, [[extension]]: extension }。
      2. 如果 prefix 包含 "-"(码元 0x002D HYPHEN-MINUS),令 posprefix 中最后一次出现 "-" 的索引;否则令 pos 为 0。
      3. pos ≥ 2 且 prefixpos - 2 到 pos - 1 的子串"-" 时重复,
        1. pos 设为 pos - 2。
      4. prefix 设为 prefix 从 0 到 pos子串
  2. 返回 undefined
当请求的语言环境包含Unicode 技术标准 #35 第一部分 核心 BCP 47 T 扩展子标签序列时,本算法中的截断可能会临时生成无效的语言标签。然而,这些无效标签都不会被返回,因为 availableLocales 仅包含有效的语言标签

9.2.4 LookupMatchingLocaleByBestFit ( availableLocales, requestedLocales )

实现自定义的抽象操作 LookupMatchingLocaleByBestFit 接受参数 availableLocales(一个可用语言环境列表)与 requestedLocales(一个语言优先级列表),返回一个Record,包含字段 [[locale]](一个Unicode 规范化语言环境标识符)与 [[extension]](一个Unicode 语言环境扩展序列empty),或 undefined。该操作在忽略Unicode 语言环境扩展序列的情况下,确定能够满足 requestedLocalesavailableLocales 的最佳元素。算法由实现决定,但应产生至少与LookupMatchingLocaleByPrefix算法相当、或更符合典型请求语言环境用户预期的结果。若找到非默认匹配,则返回一个Record,其 [[locale]] 字段包含来自 availableLocales 的匹配语言标签[[extension]] 字段包含 requestedLocales 中对应元素的Unicode 语言环境扩展序列(若请求的语言标签没有此序列,则为 empty)。

9.2.5 UnicodeExtensionComponents ( extension )

抽象操作 UnicodeExtensionComponents 接受参数 extension(一个Unicode 语言环境扩展序列),返回一个Record,包含字段 [[Attributes]][[Keywords]]。它将 extension 分解为由唯一属性组成的一个List,以及键唯一的keyword组成的一个List。属性或keyword键的重复出现会在第一次之后被忽略。调用时执行以下步骤:

  1. 断言extensionASCII-lowercase等于 extension 本身。
  2. 断言extension 从 0 到 3 的子串"-u-"
  3. attributes 为一个新的空List
  4. keywords 为一个新的空List
  5. keywordundefined
  6. sizeextension 的长度。
  7. k 为 3。
  8. k < size 时重复,
    1. eStringIndexOf(extension, "-", k)。
    2. enot-found,则令 lensize - k;否则令 lene - k
    3. subtagextensionk 起长度为 len子串
    4. 注意:一个 keyword 是一系列子标签,其中第一个是长度为 2 的键,后续(若存在)子标签的长度均位于闭区间 [3, 8] 内,并与其中间的 "-" 分隔符共同构成一个值。一个属性是位于所有keywords之前的单个子标签,其长度位于闭区间 [3, 8] 内。
    5. 断言len ≥ 2。
    6. 如果 keywordundefinedlen ≠ 2,则
      1. 如果 subtag 不是 attributes 的元素,则将其追加至 attributes
    7. 否则若 len = 2,则
      1. keyword 设为Record { [[Key]]: subtag, [[Value]]: "" }。
      2. 如果 keywords 不包含其 [[Key]] 等于 keyword.[[Key]] 的元素,则将 keyword 追加到 keywords
    8. 否则若 keyword.[[Value]] 为空字符串,则
      1. keyword.[[Value]] 设为 subtag
    9. 否则,
      1. keyword.[[Value]] 设为 keyword.[[Value]]"-"subtag字符串连接结果。
    10. k 设为 k + len + 1。
  9. 返回Record { [[Attributes]]: attributes, [[Keywords]]: keywords }。

9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, attributes, keywords )

抽象操作 InsertUnicodeExtensionAndCanonicalize 接受参数 locale(一个语言标签)、attributes(一个字符串List)与 keywords(一个由Record组成的List),返回一个Unicode 规范化语言环境标识符。它将 attributeskeywordsUnicode 语言环境扩展序列的形式合并到 locale 中,并返回规范化结果。调用时执行以下步骤:

  1. 断言locale 不包含Unicode 语言环境扩展序列
  2. extension"-u"
  3. attributes 的每个元素 attr,执行
    1. extension 设为 extension"-"attr字符串连接
  4. keywords 的每个Record { [[Key]], [[Value]] } keyword,执行
    1. extension 设为 extension"-"keyword.[[Key]]字符串连接
    2. 如果 keyword.[[Value]] 不是空字符串,则将 extension 设为 extension"-"keyword.[[Value]]字符串连接
  5. 如果 extension"-u",则返回 CanonicalizeUnicodeLocaleId(locale)。
  6. privateIndexStringIndexOf(locale, "-x-", 0)。
  7. 如果 privateIndexnot-found,则
    1. newLocalelocaleextension字符串连接
  8. 否则,
    1. preExtensionlocale 从 0 到 privateIndex子串
    2. postExtensionlocaleprivateIndex 起的子串
    3. newLocalepreExtensionextensionpostExtension字符串连接
  9. 断言IsStructurallyValidLanguageTag(newLocale) 为 true
  10. 返回 CanonicalizeUnicodeLocaleId(newLocale)。

9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData )

抽象操作 ResolveLocale 接受参数 availableLocales(一个可用语言环境列表)、requestedLocales(一个语言优先级列表)、options(一个Record)、relevantExtensionKeys(一个字符串List)与 localeData(一个Record),返回一个Record。它执行BCP 47RFC 4647 第 3 节所定义的“查找(lookup)”,使用options.[[localeMatcher]] 指定的 LookupMatchingLocaleByBestFit 算法或 LookupMatchingLocaleByPrefix 算法,忽略Unicode 语言环境扩展序列,以确定能满足 requestedLocalesavailableLocales 的最佳元素,并返回包含匹配结果的表示形式,该表示亦包含来自 localeData 的相应数据,以及 relevantExtensionKeys 每个元素的解析值(默认取自匹配语言环境的数据,若请求中存在Unicode 语言环境扩展序列则由其覆盖,随后若 options 中存在则再由其覆盖)。如果来自 requestedLocales 的匹配元素包含Unicode 语言环境扩展序列,则将其复制到返回的Record[[Locale]] 字段中的语言标签,同时省略其 keywordUnicode 语言环境非终结符中那些 key 不包含于 relevantExtensionKeys 或其 typeoptions 中不同值覆盖的项。调用时执行以下步骤:

  1. matcheroptions.[[localeMatcher]]
  2. 如果 matcher"lookup",则
    1. rLookupMatchingLocaleByPrefix(availableLocales, requestedLocales)。
  3. 否则,
    1. rLookupMatchingLocaleByBestFit(availableLocales, requestedLocales)。
  4. 如果 rundefined,则将 r 设为Record { [[locale]]: DefaultLocale(),[[extension]]: empty }。
  5. foundLocaler.[[locale]]
  6. foundLocaleDatalocaleData.[[<foundLocale>]]。
  7. 断言foundLocaleData 是一个Record
  8. result 为一个新的Record
  9. result.[[LocaleData]] 设为 foundLocaleData
  10. 如果 r.[[extension]] 不为 empty,则
    1. componentsUnicodeExtensionComponents(r.[[extension]])。
    2. keywordscomponents.[[Keywords]]
  11. 否则,
    1. keywords 为一个新的空List
  12. supportedKeywords 为一个新的空List
  13. 针对 relevantExtensionKeys 的每个元素 key,执行
    1. keyLocaleDatafoundLocaleData.[[<key>]]。
    2. 断言keyLocaleData 是一个List
    3. valuekeyLocaleData[0]。
    4. 断言value是字符串valuenull
    5. supportedKeywordempty
    6. 如果 keywords 包含其 [[Key]]key 的元素,则
      1. entrykeywords[[Key]]key 的元素。
      2. requestedValueentry.[[Value]]
      3. 如果 requestedValue 非空字符串,则
        1. 如果 keyLocaleData 包含 requestedValue,则
          1. value 设为 requestedValue
          2. supportedKeyword 设为Record { [[Key]]: key, [[Value]]: value }。
      4. 否则若 keyLocaleData 包含 "true",则
        1. value 设为 "true"
        2. supportedKeyword 设为Record { [[Key]]: key, [[Value]]: "" }。
    7. 断言options 具有字段 [[<key>]]。
    8. optionsValueoptions.[[<key>]]。
    9. 断言optionsValue是字符串,或 optionsValueundefinednull
    10. 如果 optionsValue是字符串,则
      1. ukeykeyASCII-lowercase
      2. optionsValue 设为 CanonicalizeUValue(ukey, optionsValue)。
      3. 如果 optionsValue 为空字符串,则
        1. optionsValue 设为 "true"
    11. 如果 SameValue(optionsValue, value) 为 falsekeyLocaleData 包含 optionsValue,则
      1. value 设为 optionsValue
      2. supportedKeyword 设为 empty
    12. 如果 supportedKeywordempty,则将其追加到 supportedKeywords
    13. result.[[<key>]] 设为 value
  14. 如果 supportedKeywords 非空,则
    1. supportedAttributes 为一个新的空List
    2. foundLocale 设为 InsertUnicodeExtensionAndCanonicalize(foundLocale, supportedAttributes, supportedKeywords) 的结果。
  15. result.[[Locale]] 设为 foundLocale
  16. 返回 result

9.2.8 ResolveOptions ( constructor, localeData, locales, options [ , specialBehaviours [ , modifyResolutionOptions ] ] )

抽象操作 ResolveOptions 接受参数 constructor(一个服务构造函数)、localeData(一个Record)、locales(一个ECMAScript 语言值)与 options(一个ECMAScript 语言值),以及可选参数 specialBehaviours(一个List,其元素为枚举)与 modifyResolutionOptions(一个具有一个参数的抽象闭包),返回一个正常完成,包含一个Record,其字段为 [[Options]](一个对象)、[[ResolvedLocale]](一个Record)与 [[ResolutionOptions]](一个Record),或一个抛出完成。它读取 constructor 的输入并将其解析为一个语言环境。调用时执行以下步骤:

  1. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  2. 如果 specialBehaviours 存在且包含 require-options,并且 optionsundefined,则抛出 TypeError 异常。
  3. 如果 specialBehaviours 存在且包含 coerce-options,则将 options 设为 ? CoerceOptionsToObject(options)。否则,将 options 设为 ? GetOptionsObject(options)。
  4. matcher 为 ? GetOption(options"localeMatcher"string,« "lookup""best fit" »,"best fit")。
  5. optRecord { [[localeMatcher]]: matcher }。
  6. 针对 constructor.[[ResolutionOptionDescriptors]] 的每个解析选项描述符 desc,执行
    1. 如果 desc 具有 [[Type]] 字段,则令 typedesc.[[Type]];否则令 typestring
    2. 如果 desc 具有 [[Values]] 字段,则令 valuesdesc.[[Values]];否则令 valuesempty
    3. value 为 ? GetOption(optionsdesc.[[Property]]typevaluesundefined)。
    4. 如果 valueundefined,则
      1. value 设为 ! ToString(value)。
      2. 如果 value 无法被 typeUnicode 语言环境非终结符匹配,则抛出 RangeError 异常。
    5. keydesc.[[Key]]
    6. opt.[[<key>]] 设为 value
  7. 如果 modifyResolutionOptions 存在,则执行 ! modifyResolutionOptions(opt)。
  8. resolutionResolveLocale(constructor.[[AvailableLocales]]requestedLocalesoptconstructor.[[RelevantExtensionKeys]]localeData)。
  9. 返回Record { [[Options]]: options[[ResolvedLocale]]: resolution[[ResolutionOptions]]: opt }。

9.2.9 FilterLocales ( availableLocales, requestedLocales, options )

抽象操作 FilterLocales 接受参数 availableLocales(一个可用语言环境列表)、requestedLocales(一个语言优先级列表)与 options(一个ECMAScript 语言值),返回一个正常完成,包含一个List,其中元素为Unicode 规范化语言环境标识符,或一个抛出完成。它执行BCP 47RFC 4647 第 3 节所定义的“过滤(filtering)”,在使用 LookupMatchingLocaleByBestFit 算法或 LookupMatchingLocaleByPrefix 算法(由 options 指定)时,返回 requestedLocales 中那些在 availableLocales 中存在匹配语言环境的元素,并保持其相对顺序。调用时执行以下步骤:

  1. options 设为 ? CoerceOptionsToObject(options)。
  2. matcher 为 ? GetOption(options"localeMatcher"string,« "lookup""best fit" »,"best fit")。
  3. subset 为一个新的空List
  4. 针对 requestedLocales 的每个元素 locale,执行
    1. 如果 matcher"lookup",则
      1. matchLookupMatchingLocaleByPrefix(availableLocales,« locale »)。
    2. 否则,
      1. matchLookupMatchingLocaleByBestFit(availableLocales,« locale »)。
    3. 如果 matchundefined,则将 locale 追加到 subset
  5. 返回 CreateArrayFromList(subset)。

9.2.10 GetOptionsObject ( options )

抽象操作 GetOptionsObject 接受参数 options(一个ECMAScript 语言值),返回一个正常完成,包含一个对象,或一个抛出完成。它返回一个适合与 GetOption 一起使用的对象,即 options 本身或一个默认的空对象。若 options 既非 undefined 且也非对象,则抛出 TypeError。调用时执行以下步骤:

  1. 如果 optionsundefined,则
    1. 返回 OrdinaryObjectCreate(null)。
  2. 如果 options是对象,则
    1. 返回 options
  3. 抛出 TypeError 异常。

9.2.11 CoerceOptionsToObject ( options )

抽象操作 CoerceOptionsToObject 接受参数 options(一个ECMAScript 语言值),返回一个正常完成,包含一个对象,或一个抛出完成。它将 options 强制转换为适合与 GetOption 一起使用的对象,默认为空对象。由于它会将非 null 的原始值强制转换为对象,因此不鼓励在新功能中使用它,而应优先使用 GetOptionsObject。调用时执行以下步骤:

  1. 如果 optionsundefined,则
    1. 返回 OrdinaryObjectCreate(null)。
  2. 返回 ? ToObject(options)。

9.2.12 GetOption ( options, property, type, values, default )

抽象操作 GetOption 接受参数 options(对象)、property属性键)、typebooleanstring)、valuesempty 或一个由ECMAScript 语言值组成的List)与 defaultrequired 或一个ECMAScript 语言值),返回一个正常完成,包含一个ECMAScript 语言值,或一个抛出完成。它提取 options 指定属性的值,将其转换为所需的 type,若 valuesempty 则校验其是否被允许,并在值为 undefined 时以 default 替代。调用时执行以下步骤:

  1. value 为 ? Get(optionsproperty)。
  2. 如果 valueundefined,则
    1. 如果 defaultrequired,则抛出 RangeError 异常。
    2. 返回 default
  3. 如果 typeboolean,则
    1. value 设为 ToBoolean(value)。
  4. 否则,
    1. 断言typestring
    2. value 设为 ? ToString(value)。
  5. 如果 valuesempty 且不包含 value,则抛出 RangeError 异常。
  6. 返回 value

9.2.13 GetBooleanOrStringNumberFormatOption ( options, property, stringValues, fallback )

抽象操作 GetBooleanOrStringNumberFormatOption 接受参数 options(对象)、property属性键)、stringValues(一个字符串List)与 fallback(一个ECMAScript 语言值),返回一个正常完成,包含布尔值、字符串或 fallback,或一个抛出完成。它从提供的 options 对象中提取名为 property 的属性值:若该值为 undefined,则返回 fallback;若为 true,返回 true;若其布尔强制为 false,则返回 false;否则将其强制为字符串,且若被 stringValues 允许,则返回结果。调用时执行以下步骤:

  1. value 为 ? Get(optionsproperty)。
  2. 如果 valueundefined,返回 fallback
  3. 如果 valuetrue,返回 true
  4. 如果 ToBoolean(value) 为 false,返回 false
  5. value 设为 ? ToString(value)。
  6. 如果 stringValues 不包含 value,则抛出 RangeError 异常。
  7. 返回 value

9.2.14 DefaultNumberOption ( value, minimum, maximum, fallback )

抽象操作 DefaultNumberOption 接受参数 value(一个ECMAScript 语言值)、minimum(一个整数)、maximum(一个整数)与 fallback(一个整数undefined),返回一个正常完成,包含一个整数undefined,或一个抛出完成。它将 value 转换为整数,检查其是否位于允许范围内,并在必要时填充 fallback。调用时执行以下步骤:

  1. 如果 valueundefined,返回 fallback
  2. value 设为 ? ToNumber(value)。
  3. 如果 value有限,或 (value) < minimum,或 (value) > maximum,则抛出 RangeError 异常。
  4. 返回 floor((value))。

9.2.15 GetNumberOption ( options, property, minimum, maximum, fallback )

抽象操作 GetNumberOption 接受参数 options(对象)、property(字符串)、minimum(一个整数)、maximum(一个整数)与 fallback(一个整数undefined),返回一个正常完成,包含一个整数undefined,或一个抛出完成。它从提供的 options 对象中提取名为 property 的属性值,将其转换为整数,检查是否位于允许范围,并在必要时填充 fallback。调用时执行以下步骤:

  1. value 为 ? Get(optionsproperty)。
  2. 返回 ? DefaultNumberOption(valueminimummaximumfallback)。

9.2.16 PartitionPattern ( pattern )

抽象操作 PartitionPattern 接受参数 pattern(一个模式字符串),返回一个List,其元素为Record,包含字段 [[Type]](字符串)与 [[Value]](字符串或 undefined)。当 [[Type]]"literal" 时,[[Value]] 字段为字符串值,否则为 undefined。调用时执行以下步骤:

  1. result 为一个新的空List
  2. placeholderEnd 为 -1。
  3. placeholderStartStringIndexOf(pattern"{",0)。
  4. placeholderStartnot-found 时重复,
    1. literalpatternplaceholderEnd + 1 到 placeholderStart子串
    2. 如果 literal 非空字符串,则
      1. Record { [[Type]]: "literal"[[Value]]: literal } 追加至 result
    3. placeholderEnd 设为 StringIndexOf(pattern"}"placeholderStart)。
    4. 断言placeholderEndnot-foundplaceholderStart < placeholderEnd
    5. placeholderNamepatternplaceholderStart + 1 到 placeholderEnd子串
    6. Record { [[Type]]: placeholderName[[Value]]: undefined } 追加至 result
    7. placeholderStart 设为 StringIndexOf(pattern"{"placeholderEnd)。
  5. tailpatternplaceholderEnd + 1 起的子串
  6. 如果 tail 非空字符串,则
    1. Record { [[Type]]: "literal"[[Value]]: tail } 追加至 result
  7. 返回 result

10 Collator 对象

10.1 Intl.Collator 构造函数

Intl.Collator 构造函数

  • %Intl.Collator%
  • Intl 对象"Collator" 属性的初始值。

关于 Intl 对象所有 服务构造函数属性的通用行为,见 9.1

10.1.1 Intl.Collator ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.Collator 函数时,执行以下步骤:

  1. 若 NewTarget 为 undefined,则令 newTarget活动函数对象,否则令 newTarget 为 NewTarget。
  2. internalSlotsList 为 « [[InitializedCollator]][[Locale]][[Usage]][[Collation]][[Numeric]][[CaseFirst]][[Sensitivity]][[IgnorePunctuation]][[BoundCompare]] »。
  3. collator 为 ? OrdinaryCreateFromConstructor(newTarget"%Intl.Collator.prototype%"internalSlotsList)。
  4. 注意:ResolveOptions 的语言环境数据来源取决于 options"usage" 属性,但以下两步必须在该查找之前可观察地发生(且不得在 ResolveOptions 内部被可观察地重复)。
  5. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  6. options 设为 ? CoerceOptionsToObject(options)。
  7. usage 为 ? GetOption(options"usage"string,« "sort""search" »,"sort")。
  8. collator.[[Usage]] 设为 usage
  9. usage"sort",则
    1. localeData%Intl.Collator%.[[SortLocaleData]]
  10. 否则,
    1. localeData%Intl.Collator%.[[SearchLocaleData]]
  11. optionsResolution 为 ? ResolveOptions(%Intl.Collator%localeDataCreateArrayFromList(requestedLocales), options)。
  12. roptionsResolution.[[ResolvedLocale]]
  13. collator.[[Locale]] 设为 r.[[Locale]]
  14. r.[[co]]null,令 collation"default";否则令 collationr.[[co]]
  15. collator.[[Collation]] 设为 collation
  16. collator.[[Numeric]] 设为 SameValue(r.[[kn]]"true")。
  17. collator.[[CaseFirst]] 设为 r.[[kf]]
  18. resolvedLocaleDatar.[[LocaleData]]
  19. usage"sort",令 defaultSensitivity"variant";否则令 defaultSensitivityresolvedLocaleData.[[sensitivity]]
  20. collator.[[Sensitivity]] 设为 ? GetOption(options"sensitivity"string,« "base""accent""case""variant" »,defaultSensitivity)。
  21. defaultIgnorePunctuationresolvedLocaleData.[[ignorePunctuation]]
  22. collator.[[IgnorePunctuation]] 设为 ? GetOption(options"ignorePunctuation"booleanemptydefaultIgnorePunctuation)。
  23. 返回 collator
"usage" 选项取值 "search" 所关联的排序规则仅应用于查找匹配的字符串,因为该排序规则不保证具有任何特定顺序。此行为见 Unicode 技术标准 #35 第一部分 核心,Unicode Collation Identifier 以及 Unicode 技术标准 #10 Unicode Collation Algorithm,Searching and Matching

10.2 Intl.Collator 构造函数的属性

Intl.Collator 构造函数

10.2.1 Intl.Collator.prototype

Intl.Collator.prototype 的值是 %Intl.Collator.prototype%

此属性具有如下特性 { [[Writable]]: false[[Enumerable]]: false[[Configurable]]: false }。

10.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行以下步骤:

  1. availableLocales%Intl.Collator%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocalesrequestedLocalesoptions)。

10.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 实现自定义 的前提下,受 9.1 的约束。 [[RelevantExtensionKeys]] 内部槽的值是一个 List, 该列表必须包含元素 "co",可以包含元素 "kf""kn" 中的任意一个或全部,且不得包含其他元素。

Unicode 技术标准 #35 第一部分 核心,3.6.1 节 键与类型定义 描述了十个与排序规则相关的语言环境扩展键:用于 Collator 用途与特化的 "co",用于“替代处理”的 "ka", 用于“二级权重反向”的 "kb",用于“大小写级别”的 "kc",用于“大小写优先”的 "kf", 用于“平假名第 4 级”的 "kh",用于“规范化”的 "kk",用于“数字比较”的 "kn", 用于“字符重排”的 "kr",用于“强度”的 "ks",以及用于“变量顶端”的 "vt"。 然而,Collator 要求通过 options 对象的 "usage" 属性指定用途,通过 options 对象的 "ignorePunctuation" 属性指定替代处理,通过 options 对象的 "sensitivity" 属性指定大小写级别与强度。 "co" 键在 语言标签 中仅用于 Collator 特化; 键 "kb""kh""kk""kr""vt" 在本版本的国际化 API 中不允许。其余键的支持由实现决定。

[[ResolutionOptionDescriptors]] 内部槽的值为 « { [[Key]]: "co", [[Property]]: "collation" },{ [[Key]]: "kn", [[Property]]: "numeric", [[Type]]: boolean },{ [[Key]]: "kf", [[Property]]: "caseFirst", [[Values]]: « "upper", "lower", "false" » } »。

[[SortLocaleData]][[SearchLocaleData]] 内部槽的值在 实现自定义 的前提下,受 9.1 及以下附加约束限制,对所有语言环境值 locale 均适用:

  • [[SortLocaleData]].[[<locale>]].[[co]][[SearchLocaleData]].[[<locale>]].[[co]] 的第一个元素必须为 null
  • "standard""search" 的值不得作为任何 [[SortLocaleData]].[[<locale>]].[[co]][[SearchLocaleData]].[[<locale>]].[[co]]List 中的元素。
  • [[SearchLocaleData]].[[<locale>]] 必须具有一个 [[sensitivity]] 字段,其值为字符串 "base""accent""case""variant" 之一。
  • [[SearchLocaleData]].[[<locale>]] 与 [[SortLocaleData]].[[<locale>]] 必须具有一个布尔值的 [[ignorePunctuation]] 字段。

10.3 Intl.Collator 原型对象的属性

Intl.Collator 原型对象

  • %Intl.Collator.prototype%
  • 是一个普通对象
  • 不是 Intl.Collator 实例,且不具有 [[InitializedCollator]] 内部槽,亦不具有 Intl.Collator 实例对象的任何其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

10.3.1 Intl.Collator.prototype.constructor

Intl.Collator.prototype.constructor 的初始值是 %Intl.Collator%

10.3.2 Intl.Collator.prototype.resolvedOptions ( )

此函数提供对对象初始化期间计算得到的语言环境与选项的访问。

  1. collatorthis 值。
  2. 执行 ? RequireInternalSlot(collator[[InitializedCollator]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序,对 表 3 的每一行(除表头行)执行:
    1. p 为当前行的 Property 值。
    2. vcollator 内部槽中名称为当前行 Internal Slot 值的那个槽的值。
    3. 若当前行具有 Extension Key 值,则
      1. extensionKey 为当前行的 Extension Key 值。
      2. %Intl.Collator%.[[RelevantExtensionKeys]] 不包含 extensionKey,则
        1. v 设为 undefined
    4. vundefined,则
      1. 执行 ! CreateDataPropertyOrThrow(optionspv)。
  5. 返回 options
表 3:Collator 实例的已解析选项
Internal Slot Property Extension Key
[[Locale]] "locale"
[[Usage]] "usage"
[[Sensitivity]] "sensitivity"
[[IgnorePunctuation]] "ignorePunctuation"
[[Collation]] "collation"
[[Numeric]] "numeric" "kn"
[[CaseFirst]] "caseFirst" "kf"

10.3.3 get Intl.Collator.prototype.compare

此具名存取器属性返回一个函数,该函数按照此 Collator 对象的排序顺序比较两个字符串。

Intl.Collator.prototype.compare 是一个存取器属性,其 setter 为 undefined。其 getter 执行如下步骤:

  1. collatorthis 值。
  2. 执行 ? RequireInternalSlot(collator[[InitializedCollator]])。
  3. collator.[[BoundCompare]]undefined,则
    1. F 为一个按 10.3.3.1 定义的新内建函数对象
    2. F.[[Collator]] 设为 collator
    3. collator.[[BoundCompare]] 设为 F
  4. 返回 collator.[[BoundCompare]]
返回的函数已绑定到 collator,因此可直接传给 Array.prototype.sort 或其它函数。

10.3.3.1 Collator 比较函数

Collator 比较函数是一个匿名内建函数,具有 [[Collator]] 内部槽。

当以参数 xy 调用 Collator 比较函数 F 时,执行以下步骤:

  1. collatorF.[[Collator]]
  2. 断言collator 是对象,且具有 [[InitializedCollator]] 内部槽。
  3. 若未提供 x,令 xundefined
  4. 若未提供 y,令 yundefined
  5. X 为 ? ToString(x)。
  6. Y 为 ? ToString(y)。
  7. 返回 CompareStrings(collatorXY)。

Collator 比较函数的 "length" 属性为 2𝔽

10.3.3.2 CompareStrings ( collator, x, y )

实现自定义的抽象操作 CompareStrings 接受参数 collator(一个 Intl.Collator)、x(字符串)与 y(字符串),并返回一个 Number,但不是 NaN。 返回的 Number 表示对 xy 进行实现自定义的、与语言环境相关的字符串比较的结果。 结果旨在与根据 collator 的有效语言环境与排序规则选项确定的字符串排序顺序对应:当 x 排在 y 之前时为负,之后时为正,其他情况为零(表示 xy 间没有相对顺序)。 字符串值必须被解释为 UTF-16 码元序列,如 ECMA-2626.1.4 所述;字符串中的一个代理对(0xD800 至 0xDBFF 的码元后跟 0xDC00 至 0xDFFF 的码元)必须按对应的码点解释。

如下所述行为依赖于对字符串排序元素序列(尤其是“基础字母”)的与语言环境相关的识别;不同基础字母总是比较为不相等(导致包含它们的字符串也比较为不相等)。 比较具有相同基础字母但大小写、变音符号或潜在其他方面之差异的结果,还取决于 collator.[[Sensitivity]],如下:

表 4:Collator Sensitivity 的影响
[[Sensitivity]] 描述 "a" vs. "á" "a" vs. "A"
"base" 具有相同基础字母的字符不会比较为不等,不论其大小写和/或变音符号差异。 equal equal
"accent" 具有相同基础字母的字符仅在重音和/或其他变音符号不同的情况下比较为不等,不论大小写差异。 not equal equal
"case" 具有相同基础字母的字符仅在大小写不同的情况下比较为不等,不论重音和/或其他变音符号差异。 equal not equal
"variant" 具有相同基础字母的字符只要在大小写、变音符号和/或潜在其他差异上不同就比较为不等。 not equal not equal
注 1
从输入码点到基础字母的映射可以包含任意的合并、扩展与冲突,包括对某些带变音符号字符的特别处理。例如,在瑞典语中,“ö”是与 “o” 不同的基础字母;“v” 与 “w” 被视为同一基础字母。在斯洛伐克语中,“ch” 是单个基础字母;在英语中,“æ” 是以 “a” 开始、以 “e” 结束的一串基础字母。

collator.[[IgnorePunctuation]]true,则忽略标点(例如,仅在标点上不同的字符串比较为相等)。

关于通过语言环境扩展键设置的选项之解释,见 Unicode 技术标准 #35 第一部分 核心,3.6.1 节 键与类型定义

实际返回值为实现自定义,以允许在其中编码附加信息;但对于任意给定的 collator,将此操作视为关于 xy 的函数时,要求其为定义在所有字符串集合上的 一致比较器,从而给出一个全序。 此操作还要求识别并遵循 Unicode 标准中的规范等价,包括在比较可区分但规范等价的字符串时返回 +0𝔽

注 2
建议 CompareStrings 抽象操作遵循 Unicode 技术标准 #10:Unicode Collation Algorithm 来实现,并基于 collator 的有效语言环境与排序规则选项进行裁剪。 建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的裁剪。
注 3
应用程序不应假设对于具有相同已解析选项的 Collator 实例,CompareStrings 抽象操作在同一实现的不同版本中会保持相同的行为。

10.3.4 Intl.Collator.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.Collator"

此属性具有如下特性 { [[Writable]]: false[[Enumerable]]: false[[Configurable]]: true }。

10.4 Intl.Collator 实例的属性

Intl.Collator 实例是普通对象,并从 %Intl.Collator.prototype% 继承属性。

Intl.Collator 实例具有 [[InitializedCollator]] 内部槽。

Intl.Collator 实例还具有若干由 Intl.Collator 构造函数 计算得到的内部槽:

  • [[Locale]]字符串值,表示用于排序本地化的语言环境的 语言标签
  • [[Usage]] 为字符串 "sort""search" 之一,标识 Collator 用途。
  • [[Sensitivity]] 为字符串 "base""accent""case""variant" 之一,标识 Collator 的敏感度。
  • [[IgnorePunctuation]]布尔值,指定比较中是否忽略标点。
  • [[Collation]]字符串值,表示用于排序的 Unicode Collation Identifier; 其中 "standard""search" 不允许,而 "default" 允许。

表 3 中与内部槽名称对应的键包含在 Intl.Collator 的 [[RelevantExtensionKeys]] 内部槽内,则 Intl.Collator 实例还具有以下内部槽:

  • [[Numeric]]布尔值,指定是否使用数字排序。
  • [[CaseFirst]] 为字符串 "upper""lower""false" 之一。

最后,Intl.Collator 实例具有 [[BoundCompare]] 内部槽,用于缓存 compare 存取器返回的函数(见 10.3.3)。

11 DateTimeFormat 对象

11.1 Intl.DateTimeFormat 构造函数

Intl.DateTimeFormat 构造函数

  • %Intl.DateTimeFormat%
  • Intl 对象"DateTimeFormat" 属性的初始值。

关于 Intl 对象所有 服务构造函数属性的通用行为,见 9.1

11.1.1 Intl.DateTimeFormat ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.DateTimeFormat 函数时,执行以下步骤:

  1. 若 NewTarget 为 undefined,则令 newTarget活动函数对象,否则令 newTarget 为 NewTarget。
  2. dateTimeFormat 为 ? CreateDateTimeFormat(newTargetlocalesoptionsanydate)。
  3. 若实现支持 4.3 注 1 的规范性可选构造模式,则
    1. thisthis 值。
    2. 返回 ? ChainDateTimeFormat(dateTimeFormat, NewTarget,this)。
  4. 返回 dateTimeFormat

11.1.1.1 ChainDateTimeFormat ( dateTimeFormat, newTarget, this )

抽象操作 ChainDateTimeFormat 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)、newTarget(一个ECMAScript 语言值)、this(一个ECMAScript 语言值),并返回一个正常完成,包含对象,或一个抛出完成。调用时执行以下步骤:

  1. newTargetundefined 且 ? OrdinaryHasInstance(%Intl.DateTimeFormat%this) 为 true,则
    1. 执行 ? DefinePropertyOrThrow(this%Intl%.[[FallbackSymbol]],PropertyDescriptor{ [[Value]]: dateTimeFormat[[Writable]]: false[[Enumerable]]: false[[Configurable]]: false })。
    2. 返回 this
  2. 返回 dateTimeFormat

11.1.2 CreateDateTimeFormat ( newTarget, locales, options, required, defaults )

抽象操作 CreateDateTimeFormat 接受参数 newTarget(一个构造函数)、locales(一个ECMAScript 语言值)、options(一个ECMAScript 语言值)、requireddatetimeany)、defaultsdatetimeall),返回一个正常完成,包含 DateTimeFormat 对象,或一个抛出完成。调用时执行以下步骤:

  1. dateTimeFormat 为 ? OrdinaryCreateFromConstructor(newTarget"%Intl.DateTimeFormat.prototype%",« [[InitializedDateTimeFormat]][[Locale]][[Calendar]][[NumberingSystem]][[TimeZone]][[HourCycle]][[DateStyle]][[TimeStyle]][[DateTimeFormat]][[BoundFormat]] »)。
  2. hour12undefined
  3. modifyResolutionOptions 为一个新的抽象闭包,参数为 (options),捕获 hour12,并在调用时执行如下步骤:
    1. hour12 设为 options.[[hour12]]
    2. options 移除 [[hour12]] 字段。
    3. hour12undefined,则将 options.[[hc]] 设为 null
  4. optionsResolution 为 ? ResolveOptions(%Intl.DateTimeFormat%%Intl.DateTimeFormat%.[[LocaleData]]localesoptions,« coerce-options »,modifyResolutionOptions)。
  5. options 设为 optionsResolution.[[Options]]
  6. roptionsResolution.[[ResolvedLocale]]
  7. dateTimeFormat.[[Locale]] 设为 r.[[Locale]]
  8. resolvedCalendarr.[[ca]]
  9. dateTimeFormat.[[Calendar]] 设为 resolvedCalendar
  10. dateTimeFormat.[[NumberingSystem]] 设为 r.[[nu]]
  11. resolvedLocaleDatar.[[LocaleData]]
  12. hour12true,则
    1. hcresolvedLocaleData.[[hourCycle12]]
  13. 否则若 hour12false,则
    1. hcresolvedLocaleData.[[hourCycle24]]
  14. 否则,
    1. 断言hour12undefined
    2. hcr.[[hc]]
    3. hcnull,则将 hc 设为 resolvedLocaleData.[[hourCycle]]
  15. timeZone 为 ? Get(options"timeZone")。
  16. timeZoneundefined,则
    1. timeZone 设为 SystemTimeZoneIdentifier()。
  17. 否则,
    1. timeZone 设为 ? ToString(timeZone)。
  18. IsTimeZoneOffsetString(timeZone) 为 true,则
    1. parseResultParseText(StringToCodePoints(timeZone), UTCOffset)。
    2. 断言parseResult解析节点
    3. parseResult 中包含多个 MinuteSecond 解析节点,则抛出 RangeError 异常。
    4. offsetNanosecondsParseTimeZoneOffsetString(timeZone)。
    5. offsetMinutesoffsetNanoseconds / (6 × 1010)。
    6. 断言offsetMinutes整数
    7. timeZone 设为 FormatOffsetTimeZoneIdentifier(offsetMinutes)。
  19. 否则,
    1. timeZoneIdentifierRecordGetAvailableNamedTimeZoneIdentifier(timeZone)。
    2. timeZoneIdentifierRecordempty,则抛出 RangeError 异常。
    3. timeZone 设为 timeZoneIdentifierRecord.[[PrimaryIdentifier]]
  20. dateTimeFormat.[[TimeZone]] 设为 timeZone
  21. formatOptions 为一个新的Record
  22. formatOptions.[[hourCycle]] 设为 hc
  23. hasExplicitFormatComponentsfalse
  24. 按表序,对 表 16 的每一行(除表头行)执行:
    1. prop 为当前行 Property 列给出的名称。
    2. prop"fractionalSecondDigits",则
      1. value 为 ? GetNumberOption(options"fractionalSecondDigits",1,3, undefined)。
    3. 否则,
      1. values 为一个List,其元素为当前行 Values 列给出的字符串。
      2. value 为 ? GetOption(optionspropstringvaluesundefined)。
    4. formatOptions.[[<prop>]] 设为 value
    5. valueundefined,则
      1. hasExplicitFormatComponents 设为 true
  25. formatMatcher 为 ? GetOption(options"formatMatcher"string,« "basic""best fit" »,"best fit")。
  26. dateStyle 为 ? GetOption(options"dateStyle"string,« "full""long""medium""short" »,undefined)。
  27. dateTimeFormat.[[DateStyle]] 设为 dateStyle
  28. timeStyle 为 ? GetOption(options"timeStyle"string,« "full""long""medium""short" »,undefined)。
  29. dateTimeFormat.[[TimeStyle]] 设为 timeStyle
  30. dateStyleundefinedtimeStyleundefined,则
    1. hasExplicitFormatComponentstrue,则
      1. 抛出 TypeError 异常。
    2. requireddatetimeStyleundefined,则
      1. 抛出 TypeError 异常。
    3. requiredtimedateStyleundefined,则
      1. 抛出 TypeError 异常。
    4. stylesresolvedLocaleData.[[styles]].[[<resolvedCalendar>]]。
    5. bestFormatDateTimeStyleFormat(dateStyletimeStylestyles)。
  31. 否则,
    1. needDefaultstrue
    2. requireddateany,则
      1. 对 « "weekday""year""month""day" » 的每个属性名 prop 执行:
        1. valueformatOptions.[[<prop>]]。
        2. valueundefined,则将 needDefaults 设为 false
    3. requiredtimeany,则
      1. 对 « "dayPeriod""hour""minute""second""fractionalSecondDigits" » 的每个属性名 prop 执行:
        1. valueformatOptions.[[<prop>]]。
        2. valueundefined,则将 needDefaults 设为 false
    4. needDefaultstruedefaultsdateall,则
      1. 对 « "year""month""day" » 的每个属性名 prop 执行:
        1. formatOptions.[[<prop>]] 设为 "numeric"
    5. needDefaultstruedefaultstimeall,则
      1. 对 « "hour""minute""second" » 的每个属性名 prop 执行:
        1. formatOptions.[[<prop>]] 设为 "numeric"
    6. formatsresolvedLocaleData.[[formats]].[[<resolvedCalendar>]]。
    7. formatMatcher"basic",则
      1. bestFormatBasicFormatMatcher(formatOptionsformats)。
    8. 否则,
      1. bestFormatBestFitFormatMatcher(formatOptionsformats)。
  32. dateTimeFormat.[[DateTimeFormat]] 设为 bestFormat
  33. bestFormat 具有 [[hour]] 字段,则
    1. dateTimeFormat.[[HourCycle]] 设为 hc
  34. 返回 dateTimeFormat

11.1.3 FormatOffsetTimeZoneIdentifier ( offsetMinutes )

抽象操作 FormatOffsetTimeZoneIdentifier 接受参数 offsetMinutes(一个整数),返回一个字符串。 它将 UTC 偏移(分钟)格式化为 ±HH:MM 形式的 UTC 偏移字符串。 调用时执行以下步骤:

  1. offsetMinutes ≥ 0,则令 sign 为码元 0x002B(加号);否则令 sign 为码元 0x002D(减号)。
  2. absoluteMinutesabs(offsetMinutes)。
  3. hoursfloor(absoluteMinutes / 60)。
  4. minutesabsoluteMinutes modulo 60。
  5. 返回 signToZeroPaddedDecimalString(hours,2)、码元 0x003A(冒号)、以及 ToZeroPaddedDecimalString(minutes,2) 的字符串连接。

11.2 Intl.DateTimeFormat 构造函数的属性

Intl.DateTimeFormat 构造函数

11.2.1 Intl.DateTimeFormat.prototype

Intl.DateTimeFormat.prototype 的值是 %Intl.DateTimeFormat.prototype%

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

11.2.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行以下步骤:

  1. availableLocales%Intl.DateTimeFormat%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocales, requestedLocales, options)。

11.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 实现自定义 的前提下,受 9.1 的约束。

[[RelevantExtensionKeys]] 内部槽的值为 « "ca", "hc", "nu" »。

注 1
Unicode 技术标准 #35 第一部分 核心,3.6.1 节 键与类型定义 描述了四个与日期和时间格式化相关的语言环境扩展键:"ca" 用于日历,"hc" 用于小时制,"nu" 用于(被格式化数字的)数字系统,以及 "tz" 用于时区。然而,DateTimeFormat 要求通过选项对象中的 "timeZone" 属性来指定时区。

[[ResolutionOptionDescriptors]] 内部槽的值为 « { [[Key]]: "ca", [[Property]]: "calendar" }, { [[Key]]: "nu", [[Property]]: "numberingSystem" }, { [[Key]]: "hour12", [[Property]]: "hour12", [[Type]]: boolean }, { [[Key]]: "hc", [[Property]]: "hourCycle", [[Values]]: « "h11", "h12", "h23", "h24" » } »。

[[LocaleData]] 内部槽的值在 实现自定义 的前提下,受 9.1 以及以下附加约束的限制,适用于所有语言环境值 locale

  • [[LocaleData]].[[<locale>]].[[nu]] 必须是一个 List,且不得包含值 "native", "traditio", 或 "finance"
  • [[LocaleData]].[[<locale>]].[[hc]] 必须为 « null, "h11", "h12", "h23", "h24" »。
  • [[LocaleData]].[[<locale>]].[[hourCycle]] 必须是字符串值 "h11", "h12", "h23", 或 "h24" 之一。
  • [[LocaleData]].[[<locale>]].[[hourCycle12]] 必须是字符串值 "h11""h12" 之一。
  • [[LocaleData]].[[<locale>]].[[hourCycle24]] 必须是字符串值 "h23""h24" 之一。
  • [[LocaleData]].[[<locale>]] 必须具有 [[formats]] 字段。该 [[formats]] 字段的值必须是一个 Record,并且针对每个日历值 calendar 拥有一个 [[<calendar>]] 字段。每个 [[<calendar>]] 字段的值必须是一个 List,其中包含 DateTime Format Records。该 List 中的多个 Records 可以使用相同的字段子集,只要对应的值至少在一个字段上不同即可。对每个语言环境,必须提供以下子集:
    • weekday, year, month, day, hour, minute, second, fractionalSecondDigits
    • weekday, year, month, day, hour, minute, second
    • weekday, year, month, day
    • year, month, day
    • year, month
    • month, day
    • month
    • hour, minute, second, fractionalSecondDigits
    • hour, minute, second
    • hour, minute
    • dayPeriod, hour, minute, second, fractionalSecondDigits
    • dayPeriod, hour, minute, second
    • dayPeriod, hour, minute
    • dayPeriod, hour
  • [[LocaleData]].[[<locale>]] 必须具有 [[styles]] 字段。该 [[styles]] 字段的值必须是一个 Record,并且针对每个日历值 calendar 拥有一个 [[<calendar>]] 字段。每个 [[<calendar>]] 字段的值必须是一个 DateTime Styles Record

11.2.3.1 DateTime Format Records

每个 DateTime Format Record 具有 表 5 中定义的字段。

表 5:DateTime Format Record
字段名 值类型 描述
[[weekday]] [[Weekday]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{weekday}",则存在。
[[era]] [[Era]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{era}",则存在。
[[year]] [[Year]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 至少包含以下子串之一: "{year}""{yearName}"、或 "{relatedYear}",则存在。
[[month]] [[Month]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{month}",则存在。
[[day]] [[Day]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{day}",则存在。
[[dayPeriod]] [[DayPeriod]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{dayPeriod}",则存在。
[[hour]] [[Hour]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{hour}",则存在。
[[minute]] [[Minute]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{minute}",则存在。
[[second]] [[Second]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{second}",则存在。
[[fractionalSecondDigits]] [[FractionalSecondDigits]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{fractionalSecondDigits}",则存在。
[[timeZoneName]] [[TimeZoneName]],其取值见 表 16 的 Values 列 可选字段。若 [[pattern]] 包含 子串 "{timeZoneName}",则存在。
[[pattern]] 一个 模式字符串(Pattern String) 包含该记录中每个日期与时间格式组件字段的一个 子串,以 "{" 开始,随后是字段名,最后以 "}" 结束。若记录具有 [[year]] 字段,该字符串可包含子串 "{yearName}""{relatedYear}"
[[pattern12]] 一个 模式字符串(Pattern String) 可选字段。仅当存在 [[hour]] 字段时存在。除 [[pattern]] 字段的子串外,还至少包含子串 "{ampm}""{dayPeriod}" 之一。
[[rangePatterns]] 一个 DateTime Range Pattern Record 此字段中的模式字符串与 [[pattern]] 类似。
[[rangePatterns12]] 一个 DateTime Range Pattern Record 可选字段。仅当存在 [[hour]] 字段时存在。此字段中的模式字符串与 [[pattern12]] 类似。

11.2.3.2 DateTime Range Pattern Records

每个 DateTime Range Pattern Record 具有 表 6 中定义的字段。

表 6:DateTime Range Pattern Record
字段名 值类型 描述
[[Default]] 一个 DateTime Range Pattern Format Record 当没有更具体的范围模式可用时,包含默认的范围模式。
[[Era]] 一个 DateTime Range Pattern Format Record 可选字段。当“纪元(era)”是起始与结束日期之间最大的不同日历元素时使用。
[[Year]] 一个 DateTime Range Pattern Format Record 可选字段。当“年份(year)”是起始与结束日期之间最大的不同日历元素时使用。
[[Month]] 一个 DateTime Range Pattern Format Record 可选字段。当“月份(month)”是起始与结束日期之间最大的不同日历元素时使用。
[[Day]] 一个 DateTime Range Pattern Format Record 可选字段。当“日(day)”是起始与结束日期之间最大的不同日历元素时使用。
[[AmPm]] 一个 DateTime Range Pattern Format Record 可选字段。当“上午或下午(antepost meridiem)”是起始与结束日期之间最大的不同日历元素时使用。
[[DayPeriod]] 一个 DateTime Range Pattern Format Record 可选字段。当“日间时段(day period)”是起始与结束日期之间最大的不同日历元素时使用。
[[Hour]] 一个 DateTime Range Pattern Format Record 可选字段。当“小时(hour)”是起始与结束日期之间最大的不同日历元素时使用。
[[Minute]] 一个 DateTime Range Pattern Format Record 可选字段。当“分钟(minute)”是起始与结束日期之间最大的不同日历元素时使用。
[[Second]] 一个 DateTime Range Pattern Format Record 可选字段。当“秒(second)”是起始与结束日期之间最大的不同日历元素时使用。
[[FractionalSecondDigits]] 一个 DateTime Range Pattern Format Record 可选字段。当“秒的小数部分(fractional seconds)”是起始与结束日期之间最大的不同日历元素时使用。

11.2.3.3 DateTime Range Pattern Format Records

每个 DateTime Range Pattern Format Record 具有 表 7 中定义的字段。

表 7:DateTime Range Pattern Format Record
字段名 值类型 描述
[[weekday]] [[Weekday]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{weekday}",则存在。
[[era]] [[Era]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{era}",则存在。
[[year]] [[Year]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 至少包含以下子串之一:"{year}""{yearName}"、或 "{relatedYear}",则存在。
[[month]] [[Month]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{month}",则存在。
[[day]] [[Day]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{day}",则存在。
[[dayPeriod]] [[DayPeriod]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{dayPeriod}",则存在。
[[hour]] [[Hour]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{hour}",则存在。
[[minute]] [[Minute]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{minute}",则存在。
[[second]] [[Second]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{second}",则存在。
[[fractionalSecondDigits]] [[FractionalSecondDigits]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{fractionalSecondDigits}",则存在。
[[timeZoneName]] [[TimeZoneName]],其取值见 表 16 的 Values 列 可选字段。若 [[PatternParts]] 中的某个 模式字符串(Pattern String) 包含 子串 "{timeZoneName}",则存在。
[[PatternParts]] 一个 List,其元素为 DateTime Range Pattern Part Records 每个记录表示范围模式的一部分。

11.2.3.4 DateTime Range Pattern Part Records

每个 DateTime Range Pattern Part Record 具有 表 8 中定义的字段。

表 8:DateTime Range Pattern Part Record
字段名 值类型 描述
[[Source]] "shared", "startRange", 或 "endRange" 指示范围中的哪一个日期应使用 [[Pattern]] 字段的值进行格式化。
[[Pattern]] 一个 模式字符串(Pattern String) 与常规日期模式字符串格式相同的字符串。

11.2.3.5 DateTime Styles Records

每个 DateTime Styles Record 具有 表 9 中定义的字段。

表 9:DateTime Styles Record
字段名 值类型
[[Date]] 一个 DateTime Style Record
[[Time]] 一个 DateTime Style Record
[[Connector]] 一个 DateTime Connector Record
[[DateTimeRangeFormat]] 一个 DateTime Date Range Record

11.2.3.6 DateTime Style Records

每个 DateTime Style Record 具有 表 10 中定义的字段。

表 10:DateTime Style Record
字段名 值类型 描述
[[full]] 一个 DateTime Format Record "full" 样式的格式记录。
[[long]] 一个 DateTime Format Record "long" 样式的格式记录。
[[medium]] 一个 DateTime Format Record "medium" 样式的格式记录。
[[short]] 一个 DateTime Format Record "short" 样式的格式记录。

11.2.3.7 DateTime Connector Records

每个 DateTime Connector Record 具有 表 11 中定义的字段。 所有连接器模式字符串必须包含字符串 "{0}""{1}"

表 11:DateTime Connector Record
字段名 值类型 描述
[[full]] 一个 模式字符串(Pattern String) 当日期样式为 "full" 时的连接器模式。
[[long]] 一个 模式字符串(Pattern String) 当日期样式为 "long" 时的连接器模式。
[[medium]] 一个 模式字符串(Pattern String) 当日期样式为 "medium" 时的连接器模式。
[[short]] 一个 模式字符串(Pattern String) 当日期样式为 "short" 时的连接器模式。

11.2.3.8 DateTime Date Range Records

每个 DateTime Date Range Record 具有 表 12 中定义的字段。

表 12:DateTime Date Range Record
字段名 值类型 描述
[[full]] 一个 DateTime Time Range Record 当日期样式为 "full" 时使用。
[[long]] 一个 DateTime Time Range Record 当日期样式为 "long" 时使用。
[[medium]] 一个 DateTime Time Range Record 当日期样式为 "medium" 时使用。
[[short]] 一个 DateTime Time Range Record 当日期样式为 "short" 时使用。

11.2.3.9 DateTime Time Range Records

每个 DateTime Time Range Record 具有 表 13 中定义的字段。

表 13:DateTime Time Range Record
字段名 值类型 描述
[[full]] 一个 DateTime Style Range Record 当时间样式为 "full" 时使用。
[[long]] 一个 DateTime Style Range Record 当时间样式为 "long" 时使用。
[[medium]] 一个 DateTime Style Range Record 当时间样式为 "medium" 时使用。
[[short]] 一个 DateTime Style Range Record 当时间样式为 "short" 时使用。

11.2.3.10 DateTime Style Range Records

每个 DateTime Style Range Record 具有 表 14 中定义的字段。

表 14:DateTime Style Range Record
字段名 值类型 描述
[[rangePatterns]] 一个 DateTime Range Pattern Record 用于组合日期与时间样式的范围模式。
[[rangePatterns12]] 一个 DateTime Range Pattern Record 可选字段。用于 12 小时制格式下组合日期与时间样式的范围模式。
注 2
例如,一个实现可能在其英文语言环境数据中包含以下 Record
  • [[hour]]: "numeric"
  • [[minute]]: "numeric"
  • [[pattern]]: "{hour}:{minute}"
  • [[pattern12]]: "{hour}:{minute} {ampm}"
  • [[rangePatterns]]
    • [[Hour]]
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{hour}:{minute}"}
    • [[Minute]]
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{hour}:{minute}"}
    • [[Default]]
      • [[year]]: "2-digit"
      • [[month]]: "numeric"
      • [[day]]: "numeric"
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{day}/{month}/{year}, {hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{day}/{month}/{year}, {hour}:{minute}"}
  • [[rangePatterns12]]
    • [[Hour]]
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " {ampm}"}
    • [[Minute]]
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{hour}:{minute}"}
        • {[[Source]]: "shared", [[Pattern]]: " {ampm}"}
    • [[Default]]
      • [[year]]: "2-digit"
      • [[month]]: "numeric"
      • [[day]]: "numeric"
      • [[hour]]: "numeric"
      • [[minute]]: "numeric"
      • [[PatternParts]]
        • {[[Source]]: "startRange", [[Pattern]]: "{day}/{month}/{year}, {hour}:{minute} {ampm}"}
        • {[[Source]]: "shared", [[Pattern]]: " – "}
        • {[[Source]]: "endRange", [[Pattern]]: "{day}/{month}/{year}, {hour}:{minute} {ampm}"}
注 3
建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的语言环境数据。

11.3 Intl.DateTimeFormat 原型对象的属性

Intl.DateTimeFormat 原型对象

  • %Intl.DateTimeFormat.prototype%
  • 是一个普通对象
  • 不是 Intl.DateTimeFormat 实例,且不具有 [[InitializedDateTimeFormat]] 内部槽,也不具有 Intl.DateTimeFormat 实例对象的其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

11.3.1 Intl.DateTimeFormat.prototype.constructor

Intl.DateTimeFormat.prototype.constructor 的初始值是 %Intl.DateTimeFormat%

11.3.2 Intl.DateTimeFormat.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境和选项。

  1. dtfthis 值。
  2. 若实现支持 4.3 注 1 的规范性可选构造模式,则
    1. dtf 设为 ? UnwrapDateTimeFormat(dtf)。
  3. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  4. optionsOrdinaryObjectCreate(%Object.prototype%)。
  5. 按表序,对 表 15 的每一行(除表头行)执行:
    1. p 为当前行的 Property 值。
    2. 若当前行有 Internal Slot 值,则
      1. vdtf 内部槽中名称为当前行 Internal Slot 值的槽的值。
    3. 否则,
      1. formatdtf.[[DateTimeFormat]]
      2. format 具有字段 [[<p>]],且 dtf.[[DateStyle]]undefineddtf.[[TimeStyle]]undefined,则
        1. vformat.[[<p>]]。
      3. 否则,
        1. vundefined
    4. vundefined,则
      1. 若当前行有 Conversion 值,则
        1. conversion 为当前行的 Conversion 值。
        2. conversionhour12,则
          1. v"h11""h12",则将 v 设为 true。否则,将 v 设为 false
        3. 否则,
          1. 断言conversionnumber
          2. v 设为 𝔽(v)。
      2. 执行 ! CreateDataPropertyOrThrow(options, p, v)。
  6. 返回 options
表 15:DateTimeFormat 实例的已解析选项
内部槽 属性 转换类型
[[Locale]] "locale"
[[Calendar]] "calendar"
[[NumberingSystem]] "numberingSystem"
[[TimeZone]] "timeZone"
[[HourCycle]] "hourCycle"
[[HourCycle]] "hour12" hour12
"weekday"
"era"
"year"
"month"
"day"
"dayPeriod"
"hour"
"minute"
"second"
"fractionalSecondDigits" number
"timeZoneName"
[[DateStyle]] "dateStyle"
[[TimeStyle]] "timeStyle"

出于网页兼容性考虑,如果属性 "hourCycle" 被设置,则当 "hourCycle""h11""h12" 时,"hour12" 属性应设为 true;当 "hourCycle""h23""h24" 时,"hour12" 应设为 false

注 1
在本 API 版本中,如果未在传给 Intl.DateTimeFormat 构造函数的选项对象中提供 "timeZone" 属性,则 "timeZone" 属性将为宿主环境时区的标识符。第一版在这种情况下会将 "timeZone" 属性设为 undefined
注 2
为了与第五版之前的版本兼容,"hour12" 属性会和 "hourCycle" 属性一同设置。

11.3.3 get Intl.DateTimeFormat.prototype.format

Intl.DateTimeFormat.prototype.format 是一个存取器属性,其 setter 为 undefined。getter 执行如下步骤:

  1. dtfthis 值。
  2. 若实现支持 4.3 注 1 的规范性可选构造模式,则
    1. dtf 设为 ? UnwrapDateTimeFormat(dtf)。
  3. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  4. dtf.[[BoundFormat]]undefined,则
    1. F 为一个新的内建函数对象,按 DateTime Format Functions(11.5.4)定义。
    2. F.[[DateTimeFormat]] 设为 dtf
    3. dtf.[[BoundFormat]] 设为 F
  5. 返回 dtf.[[BoundFormat]]
返回的函数已绑定到 dtf,可直接传递给 Array.prototype.map 或其他函数。 这被认为是历史遗留特性,作为一种不再用于新功能的约定,但保留以兼容现有程序。

11.3.4 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate )

当以参数 startDateendDate 调用 formatRange 方法时,执行以下步骤:

  1. dtfthis 值。
  2. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  3. startDateundefinedendDateundefined,则抛出 TypeError 异常。
  4. x 为 ? ToNumber(startDate)。
  5. y 为 ? ToNumber(endDate)。
  6. 返回 ? FormatDateTimeRange(dtf, x, y)。

11.3.5 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate )

当以参数 startDateendDate 调用 formatRangeToParts 方法时,执行以下步骤:

  1. dtfthis 值。
  2. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  3. startDateundefinedendDateundefined,则抛出 TypeError 异常。
  4. x 为 ? ToNumber(startDate)。
  5. y 为 ? ToNumber(endDate)。
  6. 返回 ? FormatDateTimeRangeToParts(dtf, x, y)。

11.3.6 Intl.DateTimeFormat.prototype.formatToParts ( date )

当以参数 date 调用 formatToParts 方法时,执行如下步骤:

  1. dtfthis 值。
  2. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  3. dateundefined,则
    1. x 为 ! Call(%Date.now%, undefined)。
  4. 否则,
    1. x 为 ? ToNumber(date)。
  5. 返回 ? FormatDateTimeToParts(dtf, x)。

11.3.7 Intl.DateTimeFormat.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.DateTimeFormat"

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

11.4 Intl.DateTimeFormat 实例的属性

Intl.DateTimeFormat 实例是普通对象,并从 %Intl.DateTimeFormat.prototype% 继承属性。

Intl.DateTimeFormat 实例具有 [[InitializedDateTimeFormat]] 内部槽。

Intl.DateTimeFormat 实例还具有若干由 Intl.DateTimeFormat 构造函数 计算得到的内部槽:

最后,Intl.DateTimeFormat 实例具有 [[BoundFormat]] 内部槽,用于缓存 format 存取器返回的函数(见 11.3.3)。

11.5 DateTimeFormat 对象的抽象操作

若干 DateTimeFormat 算法使用下表中的取值,该表给出了日期与时间格式各组件的内部槽、属性名以及允许的取值:

表 16:日期与时间格式的组成部分
字段名 属性 取值
[[Weekday]] "weekday" "narrow", "short", "long"
[[Era]] "era" "narrow", "short", "long"
[[Year]] "year" "2-digit", "numeric"
[[Month]] "month" "2-digit", "numeric", "narrow", "short", "long"
[[Day]] "day" "2-digit", "numeric"
[[DayPeriod]] "dayPeriod" "narrow", "short", "long"
[[Hour]] "hour" "2-digit", "numeric"
[[Minute]] "minute" "2-digit", "numeric"
[[Second]] "second" "2-digit", "numeric"
[[FractionalSecondDigits]] "fractionalSecondDigits" 1, 2, 3
[[TimeZoneName]] "timeZoneName" "short", "long", "shortOffset", "longOffset", "shortGeneric", "longGeneric"

11.5.1 DateTimeStyleFormat ( dateStyle, timeStyle, styles )

抽象操作 DateTimeStyleFormat 接受参数 dateStyle"full""long""medium""short"undefined)、timeStyle"full""long""medium""short"undefined),以及 styles(一个 DateTime Styles Record),并返回一个 DateTime Format Recordstyles 是从 %Intl.DateTimeFormat%.[[LocaleData]].[[<locale>]].[[styles]].[[<calendar>]] 中取得的一个 Record, 对应某个语言环境 locale 与日历 calendar。它根据参数返回合适的用于日期时间格式化的 Record。 调用时执行以下步骤:

  1. 断言dateStyleundefinedtimeStyleundefined
  2. timeStyleundefined,则
    1. 断言timeStyle"full""long""medium""short" 之一。
    2. timeFormatstyles.[[Time]].[[<timeStyle>]]。
  3. dateStyleundefined,则
    1. 断言dateStyle"full""long""medium""short" 之一。
    2. dateFormatstyles.[[Date]].[[<dateStyle>]]。
  4. dateStyleundefinedtimeStyleundefined,则
    1. format 为一个新的 DateTime Format Record
    2. dateFormat 的所有字段(除 [[pattern]][[rangePatterns]])添加至 format
    3. timeFormat 的所有字段(除 [[pattern]][[rangePatterns]][[pattern12]] 以及(若存在)[[rangePatterns12]])添加至 format
    4. connectorstyles.[[Connector]].[[<dateStyle>]]。
    5. pattern 为字符串 connector,其中将 子串 "{0}" 替换为 timeFormat.[[pattern]],并将 子串 "{1}" 替换为 dateFormat.[[pattern]]
    6. format.[[pattern]] 设为 pattern
    7. timeFormat 具有 [[pattern12]] 字段,则
      1. pattern12 为字符串 connector,其中将 子串 "{0}" 替换为 timeFormat.[[pattern12]],并将 子串 "{1}" 替换为 dateFormat.[[pattern]]
      2. format.[[pattern12]] 设为 pattern12
    8. dateTimeRangeFormatstyles.[[DateTimeRangeFormat]].[[<dateStyle>]].[[<timeStyle>]]。
    9. format.[[rangePatterns]] 设为 dateTimeRangeFormat.[[rangePatterns]]
    10. dateTimeRangeFormat 具有 [[rangePatterns12]] 字段,则
      1. format.[[rangePatterns12]] 设为 dateTimeRangeFormat.[[rangePatterns12]]
    11. 返回 format
  5. timeStyleundefined,则
    1. 返回 timeFormat
  6. 断言dateStyleundefined
  7. 返回 dateFormat

11.5.2 BasicFormatMatcher ( options, formats )

抽象操作 BasicFormatMatcher 接受参数 options(一个 Record) 与 formats(一个由 DateTime Format Records 构成的 List),并返回一个 DateTime Format Record。调用时执行如下步骤:

  1. removalPenalty 为 120。
  2. additionPenalty 为 20。
  3. longLessPenalty 为 8。
  4. longMorePenalty 为 6。
  5. shortLessPenalty 为 6。
  6. shortMorePenalty 为 3。
  7. offsetPenalty 为 1。
  8. bestScore 为 -∞。
  9. bestFormatundefined
  10. formats 的每个元素 format,执行
    1. score 为 0。
    2. 按表序,对 表 16 的每一行(除表头行)执行
      1. property 为当前行 Property 列给出的名称。
      2. options 具有字段 [[<property>]],令 optionsPropoptions.[[<property>]];否则令 optionsPropundefined
      3. format 具有字段 [[<property>]],令 formatPropformat.[[<property>]];否则令 formatPropundefined
      4. optionsPropundefinedformatPropundefined,则
        1. score 设为 score - additionPenalty
      5. 否则若 optionsPropundefinedformatPropundefined,则
        1. score 设为 score - removalPenalty
      6. 否则若 property"timeZoneName",则
        1. optionsProp"short""shortGeneric",则
          1. formatProp"shortOffset",将 score 设为 score - offsetPenalty
          2. 否则若 formatProp"longOffset",将 score 设为 score - (offsetPenalty + shortMorePenalty)。
          3. 否则若 optionsProp"short"formatProp"long",将 score 设为 score - shortMorePenalty
          4. 否则若 optionsProp"shortGeneric"formatProp"longGeneric",将 score 设为 score - shortMorePenalty
          5. 否则若 optionsPropformatProp, 将 score 设为 score - removalPenalty
        2. 否则若 optionsProp"shortOffset"formatProp"longOffset",则
          1. score 设为 score - shortMorePenalty
        3. 否则若 optionsProp"long""longGeneric",则
          1. formatProp"longOffset",将 score 设为 score - offsetPenalty
          2. 否则若 formatProp"shortOffset",将 score 设为 score - (offsetPenalty + longLessPenalty)。
          3. 否则若 optionsProp"long"formatProp"short",将 score 设为 score - longLessPenalty
          4. 否则若 optionsProp"longGeneric"formatProp"shortGeneric",将 score 设为 score - longLessPenalty
          5. 否则若 optionsPropformatProp, 将 score 设为 score - removalPenalty
        4. 否则若 optionsProp"longOffset"formatProp"shortOffset",则
          1. score 设为 score - longLessPenalty
        5. 否则若 optionsPropformatProp,则
          1. score 设为 score - removalPenalty
      7. 否则若 optionsPropformatProp,则
        1. property"fractionalSecondDigits",则
          1. values 为 « 1, 2, 3 »。
        2. 否则,
          1. values 为 « "2-digit""numeric""narrow""short""long" »。
        3. optionsPropIndexoptionsPropvalues 中的索引。
        4. formatPropIndexformatPropvalues 中的索引。
        5. deltamax(min(formatPropIndex - optionsPropIndex, 2), -2)。
        6. delta = 2,将 score 设为 score - longMorePenalty
        7. 否则若 delta = 1,将 score 设为 score - shortMorePenalty
        8. 否则若 delta = -1,将 score 设为 score - shortLessPenalty
        9. 否则若 delta = -2,将 score 设为 score - longLessPenalty
    3. score > bestScore,则
      1. bestScore 设为 score
      2. bestFormat 设为 format
  11. 返回 bestFormat

11.5.3 BestFitFormatMatcher ( options, formats )

实现自定义的抽象操作 BestFitFormatMatcher 接受参数 options(一个 Record) 与 formats(一个由 DateTime Format Records 构成的 List),并返回一个 DateTime Format Record。它返回的一组组件表示应当至少与 BasicFormatMatcher 返回的结果一样符合所选语言环境用户的习惯。

11.5.4 DateTime Format Functions

DateTime 格式函数是一个匿名内建函数,具有 [[DateTimeFormat]] 内部槽。

当以可选参数 date 调用 DateTime 格式函数 F 时,执行以下步骤:

  1. dtfF.[[DateTimeFormat]]
  2. 断言dtf 是对象,并且 dtf 具有 [[InitializedDateTimeFormat]] 内部槽。
  3. 若未提供 date 或其为 undefined,则
    1. x 为 ! Call(%Date.now%, undefined)。
  4. 否则,
    1. x 为 ? ToNumber(date)。
  5. 返回 ? FormatDateTime(dtf, x)。

DateTime 格式函数的 "length" 属性为 1𝔽

11.5.5 FormatDateTimePattern ( dateTimeFormat, format, pattern, epochNanoseconds )

抽象操作 FormatDateTimePattern 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)、format(一个 DateTime Format Record 或一个 DateTime Range Pattern Format Record)、pattern(一个 Pattern String),以及 epochNanoseconds(一个 BigInt),并返回一个带有字段 [[Type]](字符串)与 [[Value]](字符串)的 List(其元素为 Records)。 它依据 pattern 以及 dateTimeFormatformat 的有效语言环境与格式化选项,为 epoch 时间 epochNanoseconds 生成对应的分段。 调用时执行以下步骤:

  1. localedateTimeFormat.[[Locale]]
  2. nfOptionsOrdinaryObjectCreate(null)。
  3. 执行 ! CreateDataPropertyOrThrow(nfOptions"numberingSystem"dateTimeFormat.[[NumberingSystem]])。
  4. 执行 ! CreateDataPropertyOrThrow(nfOptions"useGrouping"false)。
  5. nf 为 ! Construct(%Intl.NumberFormat%,« localenfOptions »)。
  6. nf2OptionsOrdinaryObjectCreate(null)。
  7. 执行 ! CreateDataPropertyOrThrow(nf2Options"minimumIntegerDigits"2𝔽)。
  8. 执行 ! CreateDataPropertyOrThrow(nf2Options"numberingSystem"dateTimeFormat.[[NumberingSystem]])。
  9. 执行 ! CreateDataPropertyOrThrow(nf2Options"useGrouping"false)。
  10. nf2 为 ! Construct(%Intl.NumberFormat%,« localenf2Options »)。
  11. format 具有 [[fractionalSecondDigits]] 字段,则
    1. fractionalSecondDigitsformat.[[fractionalSecondDigits]]
    2. nf3OptionsOrdinaryObjectCreate(null)。
    3. 执行 ! CreateDataPropertyOrThrow(nf3Options"minimumIntegerDigits"𝔽(fractionalSecondDigits))。
    4. 执行 ! CreateDataPropertyOrThrow(nf3Options"numberingSystem"dateTimeFormat.[[NumberingSystem]])。
    5. 执行 ! CreateDataPropertyOrThrow(nf3Options"useGrouping"false)。
    6. nf3 为 ! Construct(%Intl.NumberFormat%, « localenf3Options »)。
  12. tmToLocalTime(epochNanosecondsdateTimeFormat.[[Calendar]]dateTimeFormat.[[TimeZone]])。
  13. patternPartsPartitionPattern(pattern)。
  14. result 为一个新的空 List
  15. patternParts 的每个 Record { [[Type]], [[Value]] } patternPart,执行
    1. ppatternPart.[[Type]]
    2. p"literal",则
      1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } 追加至 result
    3. 否则若 p"fractionalSecondDigits",则
      1. 断言format 具有 [[fractionalSecondDigits]] 字段。
      2. vtm.[[Millisecond]]
      3. v 设为 floor(v × 10( fractionalSecondDigits - 3 ))。
      4. fvFormatNumeric(nf3v)。
      5. Record { [[Type]]: "fractionalSecond", [[Value]]: fv } 追加至 result
    4. 否则若 p"dayPeriod",则
      1. 断言format 具有 [[dayPeriod]] 字段。
      2. fformat.[[dayPeriod]]
      3. fv 为表示 tm 的日间时段的字符串,其形式由 f 指定;该字符串取值依赖实现以及 dateTimeFormat 的有效语言环境。
      4. Record { [[Type]]: p, [[Value]]: fv } 追加至 result
    5. 否则若 p"timeZoneName",则
      1. 断言format 具有 [[timeZoneName]] 字段。
      2. fformat.[[timeZoneName]]
      3. vdateTimeFormat.[[TimeZone]]
      4. fv 为以 f 指定形式表示 v 的字符串;该字符串取值依赖实现以及 dateTimeFormat 的有效语言环境。若 f"short""long""shortOffset""longOffset",则该字符串也可依赖 tm[[InDST]] 字段值。 若实现不具备对应的本地化表示,则使用 v 本身的字符串值。
      5. Record { [[Type]]: p, [[Value]]: fv } 追加至 result
    6. 否则若 p 匹配 表 16 中某行的 Property 列,则
      1. 断言format 具有字段 [[<p>]]。
      2. fformat.[[<p>]]。
      3. vtm 中字段名等于匹配行 Internal Slot 列所给名称的那个字段的值。
      4. p"year"v ≤ 0,则将 v 设为 1 - v
      5. p"month",将 v 设为 v + 1。
      6. p"hour"dateTimeFormat.[[HourCycle]]"h11""h12",则
        1. v 设为 v modulo 12。
        2. v 为 0 且 dateTimeFormat.[[HourCycle]]"h12",将 v 设为 12。
      7. p"hour"dateTimeFormat.[[HourCycle]]"h24",则
        1. v 为 0,将 v 设为 24。
      8. f"numeric",则
        1. fvFormatNumeric(nfv)。
      9. 否则若 f"2-digit",则
        1. fvFormatNumeric(nf2v)。
        2. codePointsStringToCodePoints(fv)。
        3. countcodePoints 的元素个数。
        4. count > 2,则
          1. tenscodePoints[count - 2]。
          2. onescodePoints[count - 1]。
          3. fv 设为 CodePointsToStringtens, ones »)。
      10. 否则若 f"narrow""short""long",则
        1. fv 为以 f 指定形式表示 v 的字符串;该字符串取值依赖实现以及 dateTimeFormat 的有效语言环境与日历。若 p"month",该字符串也可依赖 format.[[day]] 是否存在。若实现不具备 f 的本地化表示,则使用 v 自身的字符串值。
      11. Record { [[Type]]: p, [[Value]]: fv } 追加至 result
    7. 否则若 p"ampm",则
      1. vtm.[[Hour]]
      2. v 大于 11,则
        1. fv 为表示 "post meridiem" 的一个 ILD 字符串。
      3. 否则,
        1. fv 为表示 "ante meridiem" 的一个 ILD 字符串。
      4. Record { [[Type]]: "dayPeriod"[[Value]]: fv } 追加至 result
    8. 否则若 p"relatedYear",则
      1. vtm.[[RelatedYear]]
      2. fvFormatNumeric(nfv)。
      3. Record { [[Type]]: "relatedYear"[[Value]]: fv } 追加至 result
    9. 否则若 p"yearName",则
      1. vtm.[[YearName]]
      2. fv 为表示 v 的一个 ILD 字符串。
      3. Record { [[Type]]: "yearName"[[Value]]: fv } 追加至 result
    10. 否则,
      1. unknown 为一个依赖实现、语言环境与数字系统的字符串,基于 epochNanosecondsp 生成。
      2. Record { [[Type]]: "unknown"[[Value]]: unknown } 追加至 result
  16. 返回 result
建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的与语言环境和日历相关的字符串;并在 DateTimeFormat 的 "short" 字符串中使用 CLDR 的 "abbreviated" 字符串,在 "long" 字符串中使用 CLDR 的 "wide" 字符串。

11.5.6 PartitionDateTimePattern ( dateTimeFormat, x )

抽象操作 PartitionDateTimePattern 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)与 x(一个 Number),并返回 正常完成,包含一个带有字段 [[Type]](字符串)与 [[Value]](字符串)的 List, 或一个 抛出完成。 它将 x 解释为 时间值(见 ECMA-26221.4.1.1),并依据 dateTimeFormat 的有效语言环境与格式化选项生成相应分段。调用时执行如下步骤:

  1. xTimeClip(x)。
  2. xNaN,抛出 RangeError 异常。
  3. epochNanoseconds((x) × 106)。
  4. formatdateTimeFormat.[[DateTimeFormat]]
  5. dateTimeFormat.[[HourCycle]]"h11""h12",则
    1. patternformat.[[pattern12]]
  6. 否则,
    1. patternformat.[[pattern]]
  7. resultFormatDateTimePattern(dateTimeFormatformatpatternepochNanoseconds)。
  8. 返回 result

11.5.7 FormatDateTime ( dateTimeFormat, x )

抽象操作 FormatDateTime 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)与 x(一个 Number),并返回 正常完成,包含一个字符串, 或一个 抛出完成。调用时执行如下步骤:

  1. parts 为 ? PartitionDateTimePattern(dateTimeFormatx)。
  2. result 为空字符串。
  3. parts 的每个 Record { [[Type]], [[Value]] } part,执行
    1. result 设为 resultpart.[[Value]]字符串连接
  4. 返回 result

11.5.8 FormatDateTimeToParts ( dateTimeFormat, x )

抽象操作 FormatDateTimeToParts 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)与 x(一个 Number),并返回 正常完成,包含一个数组, 或一个 抛出完成。调用时执行如下步骤:

  1. parts 为 ? PartitionDateTimePattern(dateTimeFormatx)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]] } part,执行
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(O"type"part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(O"value"part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O)。
    5. n 增加 1。
  5. 返回 result

11.5.9 PartitionDateTimeRangePattern ( dateTimeFormat, x, y )

抽象操作 PartitionDateTimeRangePattern 接受参数 dateTimeFormat (一个 Intl.DateTimeFormat)、x(一个 Number)与 y(一个 Number),并返回 正常完成,包含一个带有字段 [[Type]](字符串)、[[Value]](字符串)与 [[Source]](字符串)的 List, 或一个 抛出完成。 它将 xy 解释为 时间值(见 ECMA-26221.4.1.1),并依据 dateTimeFormat 的有效语言环境与格式化选项生成相应分段。调用时执行如下步骤:

  1. x 设为 TimeClip(x)。
  2. xNaN,抛出 RangeError 异常。
  3. y 设为 TimeClip(y)。
  4. yNaN,抛出 RangeError 异常。
  5. xEpochNanoseconds((x) × 106)。
  6. yEpochNanoseconds((y) × 106)。
  7. tm1ToLocalTime(xEpochNanosecondsdateTimeFormat.[[Calendar]]dateTimeFormat.[[TimeZone]])。
  8. tm2ToLocalTime(yEpochNanosecondsdateTimeFormat.[[Calendar]]dateTimeFormat.[[TimeZone]])。
  9. formatdateTimeFormat.[[DateTimeFormat]]
  10. dateTimeFormat.[[HourCycle]]"h11""h12",则
    1. patternformat.[[pattern12]]
    2. rangePatternsformat.[[rangePatterns12]]
  11. 否则,
    1. patternformat.[[pattern]]
    2. rangePatternsformat.[[rangePatterns]]
  12. selectedRangePatternundefined
  13. relevantFieldsEqualtrue
  14. checkMoreFieldstrue
  15. 按表序,对 表 6 的每一行(除表头行)执行
    1. fieldName 为当前行 Field Name 列给出的名称。
    2. rangePatterns 具有名为 fieldName 的字段,令 rangePatternrangePatterns 中名为 fieldName 的字段;否则令 rangePatternundefined
    3. selectedRangePatternundefinedrangePatternundefined,则
      1. 注:由于该字段及其以下层级不存在范围模式,不再进行进一步检查。
      2. checkMoreFields 设为 false
    4. fieldName 不等于 [[Default]]relevantFieldsEqualtruecheckMoreFieldstrue,则
      1. selectedRangePattern 设为 rangePattern
      2. fieldName[[AmPm]],则
        1. tm1.[[Hour]] 小于 12,令 v1"am";否则令 v1"pm"
        2. tm2.[[Hour]] 小于 12,令 v2"am";否则令 v2"pm"
      3. 否则若 fieldName[[DayPeriod]],则
        1. v1 为表示 tm1 日间时段的字符串;该字符串取值依赖实现以及 dateTimeFormat 的有效语言环境。
        2. v2 为表示 tm2 日间时段的字符串;该字符串取值依赖实现以及 dateTimeFormat 的有效语言环境。
      4. 否则若 fieldName[[FractionalSecondDigits]],则
        1. format 具有 [[fractionalSecondDigits]] 字段,则
          1. fractionalSecondDigitsformat.[[fractionalSecondDigits]]
        2. 否则,
          1. fractionalSecondDigits 为 3。
        3. expfractionalSecondDigits - 3。
        4. v1floor(tm1.[[Millisecond]] × 10exp)。
        5. v2floor(tm2.[[Millisecond]] × 10exp)。
      5. 否则,
        1. v1tm1 中名为 fieldName 的字段。
        2. v2tm2 中名为 fieldName 的字段。
      6. v1 不等于 v2,则
        1. relevantFieldsEqual 设为 false
  16. relevantFieldsEqualtrue,则
    1. collapsedResult 为一个新的空 List
    2. resultPartsFormatDateTimePattern(dateTimeFormatformatpatternxEpochNanoseconds)。
    3. resultParts 的每个 Record { [[Type]], [[Value]] } r,执行
      1. Record { [[Type]]: r.[[Type]][[Value]]: r.[[Value]][[Source]]: "shared" } 追加至 collapsedResult
    4. 返回 collapsedResult
  17. rangeResult 为一个新的空 List
  18. selectedRangePatternundefined,则
    1. selectedRangePattern 设为 rangePatterns.[[Default]]
  19. selectedRangePattern.[[PatternParts]] 的每个 Record { [[Pattern]], [[Source]] } rangePatternPart,执行
    1. patternrangePatternPart.[[Pattern]]
    2. sourcerangePatternPart.[[Source]]
    3. source"startRange""shared",则
      1. zxEpochNanoseconds
    4. 否则,
      1. zyEpochNanoseconds
    5. resultPartsFormatDateTimePattern(dateTimeFormatselectedRangePatternpatternz)。
    6. resultParts 的每个 Record { [[Type]], [[Value]] } r,执行
      1. Record { [[Type]]: r.[[Type]][[Value]]: r.[[Value]][[Source]]: source } 追加至 rangeResult
  20. 返回 rangeResult

11.5.10 FormatDateTimeRange ( dateTimeFormat, x, y )

抽象操作 FormatDateTimeRange 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)、x(一个 Number)与 y(一个 Number),并返回 正常完成,包含一个字符串, 或一个 抛出完成。 调用时执行如下步骤:

  1. parts 为 ? PartitionDateTimeRangePattern(dateTimeFormatxy)。
  2. result 为空字符串。
  3. parts 的每个 Record { [[Type]], [[Value]], [[Source]] } part,执行
    1. result 设为 resultpart.[[Value]]字符串连接
  4. 返回 result

11.5.11 FormatDateTimeRangeToParts ( dateTimeFormat, x, y )

抽象操作 FormatDateTimeRangeToParts 接受参数 dateTimeFormat(一个 Intl.DateTimeFormat)、x(一个 Number)与 y(一个 Number),并返回 正常完成,包含一个数组, 或一个 抛出完成。 调用时执行如下步骤:

  1. parts 为 ? PartitionDateTimeRangePattern(dateTimeFormatxy)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]], [[Source]] } part,执行
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(O"type"part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(O"value"part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(O"source"part.[[Source]])。
    5. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O)。
    6. n 增加 1。
  5. 返回 result

11.5.12 ToLocalTime ( epochNs, calendar, timeZoneIdentifier )

实现自定义的抽象操作 ToLocalTime 接受参数 epochNs(一个 BigInt)、calendar(字符串)与 timeZoneIdentifier(字符串),并返回一个 ToLocalTime Record。调用时执行如下步骤:

  1. IsTimeZoneOffsetString(timeZoneIdentifier) 为 true,则
    1. offsetNsParseTimeZoneOffsetString(timeZoneIdentifier)。
  2. 否则,
    1. 断言GetAvailableNamedTimeZoneIdentifier(timeZoneIdentifier) 非 empty
    2. offsetNsGetNamedTimeZoneOffsetNanoseconds(timeZoneIdentifierepochNs)。
  3. tz(epochNs) + offsetNs
  4. calendar"gregory",则
    1. 返回一个 ToLocalTime Record,其字段按 表 17 基于 tz 计算。
  5. 否则,
    1. 返回一个 ToLocalTime Record,其字段针对给定 calendar 基于 tz 计算。计算应使用关于该 calendar 的最佳可用信息。

11.5.13 ToLocalTime Records

每个 ToLocalTime Record 具有 表 17 中定义的字段。

表 17:由 Record 返回(来自 ToLocalTime
字段名 值类型 公历的取值计算
[[Weekday]] 一个 整数 (WeekDay(𝔽(floor(tz / 106))))
[[Era]] 一个字符串 yearYearFromTime(𝔽(floor(tz / 106)))。若 year < 1𝔽,返回 "BC",否则返回 "AD"
[[Year]] 一个 整数 (YearFromTime(𝔽(floor(tz / 106))))
[[RelatedYear]] 一个 整数undefined undefined
[[YearName]] 一个字符串或 undefined undefined
[[Month]] 一个 整数 (MonthFromTime(𝔽(floor(tz / 106))))
[[Day]] 一个 整数 (DateFromTime(𝔽(floor(tz / 106))))
[[Hour]] 一个 整数 (HourFromTime(𝔽(floor(tz / 106))))
[[Minute]] 一个 整数 (MinFromTime(𝔽(floor(tz / 106))))
[[Second]] 一个 整数 (SecFromTime(𝔽(floor(tz / 106))))
[[Millisecond]] 一个 整数 (msFromTime(𝔽(floor(tz / 106))))
[[InDST]] 一个布尔值 使用关于指定 calendartimeZoneIdentifier 的最佳可用信息进行计算,包含来自 IANA 时区数据库的当前与历史 UTC 偏移及夏令时规则信息,从而得到 truefalse

11.5.14 UnwrapDateTimeFormat ( dtf )

抽象操作 UnwrapDateTimeFormat 接受参数 dtf(一个 ECMAScript 语言值),并返回 正常完成,包含一个 ECMAScript 语言值, 或一个 抛出完成。 它返回其输入对象对应的 DateTimeFormat 实例:该实例要么是该值本身,要么是依据 4.3 注 1 中规范性可选的 构造函数模式,由 %Intl.DateTimeFormat% 与其关联的值。调用时执行如下步骤:

  1. dtf 不是对象,抛出 TypeError 异常。
  2. dtf 不具有 [[InitializedDateTimeFormat]] 内部槽,且 ? OrdinaryHasInstance(%Intl.DateTimeFormat%dtf) 为 true,则
    1. 返回 ? Get(dtf%Intl%.[[FallbackSymbol]])。
  3. 返回 dtf

12 DisplayNames 对象

12.1 Intl.DisplayNames 构造函数

Intl.DisplayNames 构造函数

  • %Intl.DisplayNames%
  • Intl 对象"DisplayNames" 属性的初始值。

Intl 对象所有 服务构造函数属性的通用行为,见 9.1

12.1.1 Intl.DisplayNames ( locales, options )

当以参数 localesoptions 调用 Intl.DisplayNames 函数时,执行以下步骤:

  1. 若 NewTarget 为 undefined,则抛出 TypeError 异常。
  2. displayNames 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.DisplayNames.prototype%",« [[InitializedDisplayNames]][[Locale]][[Style]][[Type]][[Fallback]][[LanguageDisplay]][[Fields]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.DisplayNames%%Intl.DisplayNames%.[[LocaleData]]localesoptions,« require-options »)。
  4. options 设为 optionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. style 为 ? GetOption(options"style"string,« "narrow""short""long" »,"long")。
  7. displayNames.[[Style]] 设为 style
  8. type 为 ? GetOption(options"type"string,« "language""region""script""currency""calendar""dateTimeField" »,undefined)。
  9. typeundefined,则抛出 TypeError 异常。
  10. displayNames.[[Type]] 设为 type
  11. fallback 为 ? GetOption(options"fallback"string,« "code""none" »,"code")。
  12. displayNames.[[Fallback]] 设为 fallback
  13. displayNames.[[Locale]] 设为 r.[[Locale]]
  14. resolvedLocaleDatar.[[LocaleData]]
  15. typesresolvedLocaleData.[[types]]
  16. 断言types 是一个 Record (见 12.2.3)。
  17. languageDisplay 为 ? GetOption(options"languageDisplay"string,« "dialect""standard" », "dialect")。
  18. typeFieldstypes.[[<type>]]。
  19. 断言typeFields 是一个 Record (见 12.2.3)。
  20. type"language",则
    1. displayNames.[[LanguageDisplay]] 设为 languageDisplay
    2. typeFields 设为 typeFields.[[<languageDisplay>]]。
    3. 断言typeFields 是一个 Record (见 12.2.3)。
  21. styleFieldstypeFields.[[<style>]]。
  22. 断言styleFields 是一个 Record (见 12.2.3)。
  23. displayNames.[[Fields]] 设为 styleFields
  24. 返回 displayNames

12.2 Intl.DisplayNames 构造函数的属性

Intl.DisplayNames 构造函数

12.2.1 Intl.DisplayNames.prototype

Intl.DisplayNames.prototype 的值是 %Intl.DisplayNames.prototype%

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

12.2.2 Intl.DisplayNames.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行以下步骤:

  1. availableLocales%Intl.DisplayNames%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocalesrequestedLocalesoptions)。

12.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 实现自定义 的前提下,受 9.1 的约束。

[[RelevantExtensionKeys]] 内部槽的值为 « »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « »。

[[LocaleData]] 内部槽的值在 实现自定义 的前提下,受 9.1 以及以下附加约束的限制:

  • [[LocaleData]].[[<locale>]] 对于所有语言环境值 locale 必须具有一个 [[types]] 字段。该字段的值必须是一个 Record,并且必须具有所有显示名称类型为名的字段: "language""region""script""currency""calendar""dateTimeField"
  • 字段 "language" 的值必须是一个 Record, 且必须具有以下任一有效语言显示名称为名的字段: "dialect""standard"
  • 显示名称类型 "language" 下的语言显示字段应包含 Records, 且必须具有以下任一有效显示名称样式为名的字段: "narrow""short""long"
  • 字段 "region""script""currency""calendar""dateTimeField" 的值必须是 Records, 且必须具有所有显示名称样式为名的字段: "narrow""short""long"
  • 显示名称类型 "language" 下的显示名称样式字段应包含 Records, 键应对应于可由 unicode_language_id Unicode locale nonterminal 匹配的语言代码。该等字段的值必须是字符串。
  • 显示名称类型 "region" 下的显示名称样式字段应包含 Records, 键应对应于区域代码。该等字段的值必须是字符串。
  • 显示名称类型 "script" 下的显示名称样式字段应包含 Records, 键应对应于书写系统代码。该等字段的值必须是字符串。
  • 显示名称类型 "currency" 下的显示名称样式字段应包含 Records, 键应对应于货币代码。该等字段的值必须是字符串。
  • 显示名称类型 "calendar" 下的显示名称样式字段应包含 Records, 键应对应于可由 type Unicode locale nonterminal 匹配的日历标识符。该等字段的值必须是字符串。
  • 显示名称类型 "dateTimeField" 下的显示名称样式字段应包含 Records, 键应对应于 表 19 中列出的代码。该等字段的值必须是字符串。
建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的语言环境数据。

12.3 Intl.DisplayNames 原型对象的属性

Intl.DisplayNames 原型对象

  • %Intl.DisplayNames.prototype%
  • 是一个普通对象
  • 不是 Intl.DisplayNames 实例,且不具有 [[InitializedDisplayNames]] 内部槽,也不具有 Intl.DisplayNames 实例对象的其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

12.3.1 Intl.DisplayNames.prototype.constructor

Intl.DisplayNames.prototype.constructor 的初始值是 %Intl.DisplayNames%

12.3.2 Intl.DisplayNames.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境与选项。

  1. displayNamesthis 值。
  2. 执行 ? RequireInternalSlot(displayNames[[InitializedDisplayNames]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序,对 表 18 的每一行(除表头行)执行:
    1. p 为当前行的 Property 值。
    2. vdisplayNames 内部槽中名称为当前行 Internal Slot 值的槽的值。
    3. 断言vundefined
    4. 执行 ! CreateDataPropertyOrThrow(optionspv)。
  5. 返回 options
表 18:DisplayNames 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[Style]] "style"
[[Type]] "type"
[[Fallback]] "fallback"
[[LanguageDisplay]] "languageDisplay"

12.3.3 Intl.DisplayNames.prototype.of ( code )

当以参数 code 调用 Intl.DisplayNames.prototype.of 时,执行以下步骤:

  1. displayNamesthis 值。
  2. 执行 ? RequireInternalSlot(displayNames[[InitializedDisplayNames]])。
  3. code 为 ? ToString(code)。
  4. code 设为 ? CanonicalCodeForDisplayNames(displayNames.[[Type]]code)。
  5. fieldsdisplayNames.[[Fields]]
  6. fields 具有字段 [[<code>]],则返回 fields.[[<code>]]。
  7. displayNames.[[Fallback]]"code",则返回 code
  8. 返回 undefined

12.3.4 Intl.DisplayNames.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.DisplayNames"

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

12.4 Intl.DisplayNames 实例的属性

Intl.DisplayNames 实例是普通对象,并从 %Intl.DisplayNames.prototype% 继承属性。

Intl.DisplayNames 实例具有 [[InitializedDisplayNames]] 内部槽。

Intl.DisplayNames 实例还具有若干由 Intl.DisplayNames 构造函数 计算得到的内部槽:

  • [[Locale]] 为字符串值,表示用于格式化的语言环境的 语言标签
  • [[Style]] 为字符串值 "narrow""short""long" 之一,标识所用的显示名称样式。
  • [[Type]] 为字符串值 "language""region""script""currency""calendar""dateTimeField" 之一,标识所请求的显示名称类型。
  • [[Fallback]] 为字符串值 "code""none" 之一,标识当系统没有所请求的显示名称时的回退返回值。
  • [[LanguageDisplay]] 为字符串值 "dialect""standard" 之一,标识语言显示方式。仅当 [[Type]] 的值为 "language" 时使用。
  • [[Fields]] 是一个 Record (见 12.2.3),必须具有以代码为键的字段,且与 [[Style]][[Type]][[LanguageDisplay]] 相对应。

12.5 DisplayNames 对象的抽象操作

12.5.1 CanonicalCodeForDisplayNames ( type, code )

抽象操作 CanonicalCodeForDisplayNames 接受参数 type(字符串)与 code(字符串),并返回 正常完成,包含一个字符串, 或一个 抛出完成。 它验证 code 是否根据 type 表示格式良好的代码,并返回 code 的大小写规范化形式。调用时执行以下步骤:

  1. type"language",则
    1. code 不能被 unicode_language_id Unicode locale nonterminal 匹配, 则抛出 RangeError 异常。
    2. IsStructurallyValidLanguageTag(code) 为 false,则抛出 RangeError 异常。
    3. 返回 CanonicalizeUnicodeLocaleId(code)。
  2. type"region",则
    1. code 不能被 unicode_region_subtag Unicode locale nonterminal 匹配, 则抛出 RangeError 异常。
    2. 返回 ASCII-uppercase(code)。
  3. type"script",则
    1. code 不能被 unicode_script_subtag Unicode locale nonterminal 匹配, 则抛出 RangeError 异常。
    2. 断言code 的长度为 4,且 code 的每个代码单元均为 ASCII 字母(0x0041 到 0x005A 与 0x0061 到 0x007A,含边界)。
    3. firstASCII-uppercase(code子串,从 0 到 1)。
    4. restASCII-lowercase(code子串,从 1 开始)。
    5. 返回 字符串连接(firstrest)。
  4. type"calendar",则
    1. code 不能被 type Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
    2. code 使用了 Unicode 技术标准 #35 第一部分 核心,3.3 节 BCP 47 一致性 中描述的任一向后兼容语法,则抛出 RangeError 异常。
    3. 返回 ASCII-lowercase(code)。
  5. type"dateTimeField",则
    1. IsValidDateTimeFieldCode(code) 的结果为 false,则抛出 RangeError 异常。
    2. 返回 code
  6. 断言type"currency"
  7. IsWellFormedCurrencyCode(code) 为 false,则抛出 RangeError 异常。
  8. 返回 ASCII-uppercase(code)。

12.5.2 IsValidDateTimeFieldCode ( field )

抽象操作 IsValidDateTimeFieldCode 接受参数 field(字符串),并返回一个布尔值。它验证参数 field 是否表示一个有效的日期时间字段代码。调用时执行以下步骤:

  1. field 列于 表 19 的 Code 列中,则返回 true
  2. 返回 false
表 19:DisplayNames 的日期时间字段代码
代码 描述
"era" 表示纪元的字段,例如公历或儒略历中的 AD 或 BC。
"year" 表示年份(处于某个纪元内)的字段。
"quarter" 表示季度的字段,例如 Q2、第二季度等。
"month" 表示月份的字段,例如 Sep、September 等。
"weekOfYear" 表示一年中的周序号的字段。
"weekday" 表示星期几的字段,例如 Tue、Tuesday 等。
"day" 表示某月中的日的字段。
"dayPeriod" 表示日间时段的字段,可以是 am、pm 等,或 noon、evening 等。
"hour" 表示小时的字段。
"minute" 表示分钟的字段。
"second" 表示秒的字段。
"timeZoneName" 表示时区名称的字段,例如 PDT、Pacific Daylight Time 等。

13 DurationFormat 对象

13.1 Intl.DurationFormat 构造函数

Intl.DurationFormat 构造函数

  • %Intl.DurationFormat%
  • Intl 对象"DurationFormat" 属性的初始值。

Intl 对象所有 服务构造函数属性的通用行为,见 9.1

13.1.1 Intl.DurationFormat ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.DurationFormat 函数时,执行如下步骤:

  1. 如果 NewTarget 为 undefined,则抛出 TypeError 异常。
  2. durationFormat 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.DurationFormatPrototype%", « [[InitializedDurationFormat]], [[Locale]], [[NumberingSystem]], [[Style]], [[YearsOptions]], [[MonthsOptions]], [[WeeksOptions]], [[DaysOptions]], [[HoursOptions]], [[MinutesOptions]], [[SecondsOptions]], [[MillisecondsOptions]], [[MicrosecondsOptions]], [[NanosecondsOptions]], [[HourMinuteSeparator]], [[MinuteSecondSeparator]], [[FractionalDigits]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.DurationFormat%, %Intl.DurationFormat%.[[LocaleData]], locales, options)。
  4. options 设为 optionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. durationFormat.[[Locale]] 设为 r.[[Locale]]
  7. resolvedLocaleDatar.[[LocaleData]]
  8. digitalFormatresolvedLocaleData.[[DigitalFormat]]
  9. durationFormat.[[HourMinuteSeparator]] 设为 digitalFormat.[[HourMinuteSeparator]]
  10. durationFormat.[[MinuteSecondSeparator]] 设为 digitalFormat.[[MinuteSecondSeparator]]
  11. durationFormat.[[NumberingSystem]] 设为 r.[[nu]]
  12. style 为 ? GetOption(options, "style", string, « "long", "short", "narrow", "digital" », "short")。
  13. durationFormat.[[Style]] 设为 style
  14. prevStyle 为空字符串。
  15. 按表序,对 表 20 的每一行(除表头行)执行:
    1. slot 为当前行 Internal Slot 列的值。
    2. unit 为当前行 Unit 列的值。
    3. styles 为当前行 Styles 列的值。
    4. digitalBase 为当前行 Digital Default 列的值。
    5. unitOptions 为 ? GetDurationUnitOptions(unit, options, style, styles, digitalBase, prevStyle, digitalFormat.[[TwoDigitHours]])。
    6. durationFormat 的名为 slot 的内部槽值设为 unitOptions
    7. 如果 unit"hours""minutes""seconds""milliseconds""microseconds" 之一,则
      1. prevStyle 设为 unitOptions.[[Style]]
  16. durationFormat.[[FractionalDigits]] 设为 ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined)。
  17. 返回 durationFormat
表 20:DurationFormat 实例的内部槽及属性名
内部槽 单位 样式 数字默认样式
[[YearsOptions]] "years" « "long", "short", "narrow" » "short"
[[MonthsOptions]] "months" « "long", "short", "narrow" » "short"
[[WeeksOptions]] "weeks" « "long", "short", "narrow" » "short"
[[DaysOptions]] "days" « "long", "short", "narrow" » "short"
[[HoursOptions]] "hours" « "long", "short", "narrow", "numeric", "2-digit" » "numeric"
[[MinutesOptions]] "minutes" « "long", "short", "narrow", "numeric", "2-digit" » "numeric"
[[SecondsOptions]] "seconds" « "long", "short", "narrow", "numeric", "2-digit" » "numeric"
[[MillisecondsOptions]] "milliseconds" « "long", "short", "narrow", "numeric" » "numeric"
[[MicrosecondsOptions]] "microseconds" « "long", "short", "narrow", "numeric" » "numeric"
[[NanosecondsOptions]] "nanoseconds" « "long", "short", "narrow", "numeric" » "numeric"

13.2 Intl.DurationFormat 构造函数的属性

Intl.DurationFormat 构造函数

13.2.1 Intl.DurationFormat.prototype

Intl.DurationFormat.prototype 的值为 %Intl.DurationFormat.prototype%

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

13.2.2 Intl.DurationFormat.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行以下步骤:

  1. availableLocales%Intl.DurationFormat%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocalesrequestedLocalesoptions)。

13.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 的约束下由实现定义。

[[RelevantExtensionKeys]] 内部槽的值为 « "nu" »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « { [[Key]]: "nu", [[Property]]: "numberingSystem" } »。

[[LocaleData]] 内部槽的值在 实现自定义 的前提下,受 9.1 及以下附加约束限制,针对所有语言环境值 locale

  • [[LocaleData]].[[<locale>]] 必须是一个 Record, 具有字段 [[nu]][[DigitalFormat]]
  • [[LocaleData]].[[<locale>]].[[nu]] 必须是一个 List, 参见 16.2.3,且不得包含值 "native""traditio""finance"
  • [[LocaleData]].[[<locale>]].[[DigitalFormat]] 必须是一个 Record, 键对应于该语言环境可用的每个数字系统。与这些键关联的值必须是 Record, 并包含以下字段:
    • [[HourMinuteSeparator]] 必须是字符串值,表示在使用 "numeric""2-digit" 样式时该语言环境和数字系统下小时与分钟之间的分隔符。
    • [[MinuteSecondSeparator]] 必须是字符串值,表示在使用 "numeric""2-digit" 样式时该语言环境和数字系统下分钟与秒之间的分隔符。
    • [[TwoDigitHours]] 必须是布尔值,指示在使用 "numeric" 样式时小时是否总以两位数字展示。
建议实现使用通用语言环境数据存储库(CLDR,http://cldr.unicode.org/)提供的语言环境数据。

13.3 Intl.DurationFormat 原型对象的属性

Intl.DurationFormat 原型对象

  • %Intl.DurationFormat.prototype%
  • 是一个普通对象
  • 不是 Intl.DurationFormat 实例,且不具有 [[InitializedDurationFormat]] 内部槽,也不具有 Intl.DurationFormat 实例对象的其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

13.3.1 Intl.DurationFormat.prototype.constructor

Intl.DurationFormat.prototype.constructor 的初始值为内在对象 %Intl.DurationFormat%

13.3.2 Intl.DurationFormat.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境和选项。

  1. dfthis 值。
  2. 执行 ? RequireInternalSlot(df[[InitializedDurationFormat]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序,对 表 21 的每一行(除表头行)执行:
    1. p 为当前行 Property 值。
    2. vdf 内部槽中名称为当前行 Internal Slot 值的槽的值。
    3. vundefined,则
      1. 若当前行有 Conversion 值,则令 conversion 为该值;否则令 conversionempty
      2. conversionnumber,则
        1. v 设为 𝔽(v)。
      3. 否则若 conversionempty,则
        1. 断言conversionstyle+displayvDuration Unit Options Record
        2. 注:v.[[Style]] 将以名为 p(复数 Temporal 单位)的属性表示,v.[[Display]] 将以名为 p 后缀 "Display" 的属性表示。
        3. stylev.[[Style]]
        4. style"fractional",则
          1. 断言IsFractionalSecondUnitName(p) 为 true
          2. style 设为 "numeric"
        5. 执行 ! CreateDataPropertyOrThrow(optionspstyle)。
        6. p 设为 字符串连接(p"Display")。
        7. v 设为 v.[[Display]]
      4. 执行 ! CreateDataPropertyOrThrow(optionspv)。
  5. 返回 options
表 21:DurationFormat 实例的已解析选项
内部槽 属性 转换类型
[[Locale]] "locale"
[[NumberingSystem]] "numberingSystem"
[[Style]] "style"
[[YearsOptions]] "years" style+display
[[MonthsOptions]] "months" style+display
[[WeeksOptions]] "weeks" style+display
[[DaysOptions]] "days" style+display
[[HoursOptions]] "hours" style+display
[[MinutesOptions]] "minutes" style+display
[[SecondsOptions]] "seconds" style+display
[[MillisecondsOptions]] "milliseconds" style+display
[[MicrosecondsOptions]] "microseconds" style+display
[[NanosecondsOptions]] "nanoseconds" style+display
[[FractionalDigits]] "fractionalDigits" number

13.3.3 Intl.DurationFormat.prototype.format ( duration )

当以参数 duration 调用 format 方法时,执行以下步骤:

  1. dfthis 值。
  2. 执行 ? RequireInternalSlot(df[[InitializedDurationFormat]])。
  3. record 为 ? ToDurationRecord(duration)。
  4. partsPartitionDurationFormatPattern(dfrecord)。
  5. result 为空字符串。
  6. parts 的每个 Record { [[Type]], [[Value]], [[Unit]] } part,执行
    1. result 设为 resultpart.[[Value]]字符串连接
  7. 返回 result

13.3.4 Intl.DurationFormat.prototype.formatToParts ( duration )

当以参数 duration 调用 formatToParts 方法时,执行以下步骤:

  1. dfthis 值。
  2. 执行 ? RequireInternalSlot(df, [[InitializedDurationFormat]])。
  3. record 为 ? ToDurationRecord(duration)。
  4. partsPartitionDurationFormatPattern(df, record)。
  5. result 为 ! ArrayCreate(0)。
  6. n 为 0。
  7. parts 中的每个 Record { [[Type]], [[Value]], [[Unit]] } part,执行
    1. objOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(obj, "type", part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(obj, "value", part.[[Value]])。
    4. part.[[Unit]]empty,则执行 ! CreateDataPropertyOrThrow(obj, "unit", part.[[Unit]])。
    5. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(n), obj)。
    6. n 设为 n + 1。
  8. 返回 result

13.3.5 Intl.DurationFormat.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.DurationFormat"

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

13.4 Intl.DurationFormat 实例的属性

Intl.DurationFormat 实例从 %Intl.DurationFormat.prototype% 继承属性。

Intl.DurationFormat 实例具有一个 [[InitializedDurationFormat]] 内部槽。

Intl.DurationFormat 实例还具有若干由 Intl.DurationFormat 构造函数 计算得到的内部槽:

13.5 DurationFormat 对象的抽象操作

13.5.1 Duration 记录

Duration Record 是用于表示持续时间的一个Record 值。

Duration Record 具有 表 22 中列出的字段。

表 22:Duration Record 字段
字段名 含义
[[Years]] 持续时间中的年数。
[[Months]] 持续时间中的月数。
[[Weeks]] 持续时间中的周数。
[[Days]] 持续时间中的天数。
[[Hours]] 持续时间中的小时数。
[[Minutes]] 持续时间中的分钟数。
[[Seconds]] 持续时间中的秒数。
[[Milliseconds]] 持续时间中的毫秒数。
[[Microseconds]] 持续时间中的微秒数。
[[Nanoseconds]] 持续时间中的纳秒数。

13.5.2 ToIntegerIfIntegral ( argument )

抽象操作 ToIntegerIfIntegral 接受参数 argument(一个ECMAScript 语言值),并返回一个正常完成,包含一个整数,或者一个抛出完成。它将 argument 转换为表示其 Number 值的整数;当该值不是整数值时抛出 RangeError。调用时执行以下步骤:

  1. number 为 ? ToNumber(argument)。
  2. number 不是一个整数 Number,则抛出 RangeError 异常。
  3. 返回 (number)。

13.5.3 ToDurationRecord ( input )

抽象操作 ToDurationRecord 接受参数 input(一个ECMAScript 语言值),并返回一个正常完成,包含一个Duration Record,或者一个抛出完成。它将给定的表示持续时间的对象转换为一个Duration Record。调用时执行以下步骤:

  1. input不是对象,则
    1. input是字符串,抛出 RangeError 异常。
    2. 抛出 TypeError 异常。
  2. result 为一个新的 Duration Record,其每个字段均设为 0。
  3. days 为 ? Get(input"days")。
  4. daysundefined,将 result.[[Days]] 设为 ? ToIntegerIfIntegral(days)。
  5. hours 为 ? Get(input"hours")。
  6. hoursundefined,将 result.[[Hours]] 设为 ? ToIntegerIfIntegral(hours)。
  7. microseconds 为 ? Get(input"microseconds")。
  8. microsecondsundefined,将 result.[[Microseconds]] 设为 ? ToIntegerIfIntegral(microseconds)。
  9. milliseconds 为 ? Get(input"milliseconds")。
  10. millisecondsundefined,将 result.[[Milliseconds]] 设为 ? ToIntegerIfIntegral(milliseconds)。
  11. minutes 为 ? Get(input"minutes")。
  12. minutesundefined,将 result.[[Minutes]] 设为 ? ToIntegerIfIntegral(minutes)。
  13. months 为 ? Get(input"months")。
  14. monthsundefined,将 result.[[Months]] 设为 ? ToIntegerIfIntegral(months)。
  15. nanoseconds 为 ? Get(input"nanoseconds")。
  16. nanosecondsundefined,将 result.[[Nanoseconds]] 设为 ? ToIntegerIfIntegral(nanoseconds)。
  17. seconds 为 ? Get(input"seconds")。
  18. secondsundefined,将 result.[[Seconds]] 设为 ? ToIntegerIfIntegral(seconds)。
  19. weeks 为 ? Get(input"weeks")。
  20. weeksundefined,将 result.[[Weeks]] 设为 ? ToIntegerIfIntegral(weeks)。
  21. years 为 ? Get(input"years")。
  22. yearsundefined,将 result.[[Years]] 设为 ? ToIntegerIfIntegral(years)。
  23. yearsmonthsweeksdayshoursminutessecondsmillisecondsmicrosecondsnanoseconds 全为 undefined,则抛出 TypeError 异常。
  24. IsValidDuration( result.[[Years]]result.[[Months]]result.[[Weeks]]result.[[Days]]result.[[Hours]]result.[[Minutes]]result.[[Seconds]]result.[[Milliseconds]]result.[[Microseconds]]result.[[Nanoseconds]]) 为 false,则
    1. 抛出 RangeError 异常。
  25. 返回 result

13.5.4 DurationSign ( duration )

抽象操作 DurationSign 接受参数 duration(一个Duration Record)并返回 -1、0 或 1。若 duration 参数中最显著的非零字段为正,则返回 1;若最显著的非零字段为负,则返回 -1。若 duration 的所有字段均为 0,则返回 0。调用时执行以下步骤:

  1. 对 « duration.[[Years]]duration.[[Months]]duration.[[Weeks]]duration.[[Days]]duration.[[Hours]]duration.[[Minutes]]duration.[[Seconds]]duration.[[Milliseconds]]duration.[[Microseconds]]duration.[[Nanoseconds]] » 中的每个值 v,执行
    1. v < 0,返回 -1。
    2. v > 0,返回 1。
  2. 返回 0。

13.5.5 IsValidDuration ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds )

抽象操作 IsValidDuration 接受参数 years(一个整数)、months(一个整数)、weeks(一个整数)、days(一个整数)、hours(一个整数)、minutes(一个整数)、seconds(一个整数)、milliseconds(一个整数)、microseconds(一个整数)以及 nanoseconds(一个整数),并返回一个布尔值。若其参数可构成用于构造一个Duration Record的有效输入,则返回 true;否则返回 false。调用时执行以下步骤:

  1. sign 为 0。
  2. 对 « yearsmonthsweeksdayshoursminutessecondsmillisecondsmicrosecondsnanoseconds » 中的每个值 v,执行
    1. 𝔽(v) 非有限,返回 false
    2. v < 0,则
      1. sign > 0,返回 false
      2. sign 设为 -1。
    3. 否则若 v > 0,则
      1. sign < 0,返回 false
      2. sign 设为 1。
  3. abs(years) ≥ 232,返回 false
  4. abs(months) ≥ 232,返回 false
  5. abs(weeks) ≥ 232,返回 false
  6. normalizedSecondsdays × 86,400 + hours × 3600 + minutes × 60 + seconds + (𝔽(milliseconds)) × 10-3 + (𝔽(microseconds)) × 10-6 + (𝔽(nanoseconds)) × 10-9
  7. 注:上述步骤不能直接用浮点运算实现。当 millisecondsmicrosecondsnanoseconds 是不安全的整数时,分别乘以 10-3、10-6 与 10-9 可能不精确。该乘法可在 C++ 中通过具有足够商位数的 std::remquo() 的实现来完成。字符串处理也可得到精确结果,因为乘数是 10 的幂。
  8. abs(normalizedSeconds) ≥ 253,返回 false
  9. 返回 true

13.5.6 GetDurationUnitOptions ( unit, options, baseStyle, stylesList, digitalBase, prevStyle, twoDigitHours )

抽象操作 GetDurationUnitOptions 接受参数 unit(字符串)、options(对象)、baseStyle(字符串)、stylesList(一个由字符串构成的List)、digitalBase(字符串)、prevStyle(字符串)与 twoDigitHours(布尔值),并返回一个正常完成,包含一个Duration Unit Options Record,或一个抛出完成。它从对象中提取任意给定 unit 的相关选项,并以一个Record返回。调用时执行以下步骤:

  1. style 为 ? GetOption(optionsunitstringstylesListundefined)。
  2. displayDefault"always"
  3. styleundefined,则
    1. baseStyle"digital",则
      1. style 设为 digitalBase
      2. unit"hours""minutes""seconds" 之一,将 displayDefault 设为 "auto"
    2. 否则若 prevStyle"fractional""numeric""2-digit" 之一,则
      1. style 设为 "numeric"
      2. unit 不是 "minutes""seconds",将 displayDefault 设为 "auto"
    3. 否则,
      1. style 设为 baseStyle
      2. displayDefault 设为 "auto"
  4. style"numeric"IsFractionalSecondUnitName(unit) 为 true,则
    1. style 设为 "fractional"
    2. displayDefault 设为 "auto"
  5. displayField字符串连接(unit"Display")。
  6. display 为 ? GetOption(optionsdisplayFieldstring,« "auto""always" »,displayDefault)。
  7. 执行 ? ValidateDurationUnitStyle(unitstyledisplayprevStyle)。
  8. unit"hours"twoDigitHourstrue,将 style 设为 "2-digit"
  9. unit"minutes""seconds"prevStyle"numeric""2-digit",将 style 设为 "2-digit"
  10. 返回 Duration Unit Options Record { [[Style]]: style[[Display]]: display }。

13.5.6.1 Duration Unit Options 记录

每个 Duration Unit Options Record 具有 表 23 中定义的字段。

表 23:Duration Unit Options Record
字段名 值类型
[[Style]] 来自 表 20 的样式列的字符串
[[Display]] "auto""always"

13.5.6.2 ValidateDurationUnitStyle ( unit, style, display, prevStyle )

抽象操作 ValidateDurationUnitStyle 接受参数 unit(字符串)、style(字符串)、display(字符串)与 prevStyle(字符串),并返回一个正常完成,包含unused,或一个抛出完成。调用时执行以下步骤:

  1. display"always"style"fractional",抛出 RangeError 异常。
  2. prevStyle"fractional"style"fractional",抛出 RangeError 异常。
  3. prevStyle"numeric""2-digit"style 不属于 "fractional""numeric""2-digit",抛出 RangeError 异常。
  4. 返回 unused
上述算法未引用 unit,但建议实现于构造抛出异常的信息时使用该参数。

13.5.7 ComputeFractionalDigits ( durationFormat, duration )

抽象操作 ComputeFractionalDigits 接受参数 durationFormat(一个 DurationFormat 对象)与 duration(一个Duration Record),并返回一个数学值。它计算 durationFormat 中所有使用 "fractional" 样式的单位的值之和,并以不使用 "fractional" 样式的最小单位为分母的分数形式表示。调用时执行以下步骤:

  1. result 为 0。
  2. exponent 为 3。
  3. 按表序,对 表 24 的每一行(除表头行)执行:
    1. unitOptionsdurationFormat 中名为当前行 Internal Slot 值的内部槽的值。
    2. unitOptions.[[Style]]"fractional",则
      1. unit 为当前行 Unit 列的值。
      2. 断言IsFractionalSecondUnitName(unit) 为 true
      3. valueduration 中名称为当前行 Value Field 值的字段之值。
      4. result 设为 result + (value / 10exponent)。
      5. exponent 设为 exponent + 3。
  4. 返回 result

13.5.8 NextUnitFractional ( durationFormat, unit )

抽象操作 NextUnitFractional 接受参数 durationFormat(一个 DurationFormat 对象)与 unit(字符串),并返回一个布尔值。若下一个更小的单位使用 "fractional" 样式,则返回 true。调用时执行以下步骤:

  1. unit"seconds"durationFormat.[[MillisecondsOptions]].[[Style]]"fractional",返回 true
  2. unit"milliseconds"durationFormat.[[MicrosecondsOptions]].[[Style]]"fractional",返回 true
  3. unit"microseconds"durationFormat.[[NanosecondsOptions]].[[Style]]"fractional",返回 true
  4. 返回 false

13.5.9 FormatNumericHours ( durationFormat, hoursValue, signDisplayed )

抽象操作 FormatNumericHours 接受参数 durationFormat(一个 DurationFormat 对象)、hoursValue(一个整数)与 signDisplayed(布尔值),并返回一个List(其元素为Records)。hoursValue 为一个表示小时数的整数。该操作根据有效语言环境与 durationFormat 的格式化选项,为 hoursValue 生成分段。调用时执行以下步骤:

  1. result 为一个新的空List
  2. hoursStyledurationFormat.[[HoursOptions]].[[Style]]
  3. 断言hoursStyle"numeric"hoursStyle"2-digit"
  4. nfOptsOrdinaryObjectCreate(null)。
  5. numberingSystemdurationFormat.[[NumberingSystem]]
  6. 执行 ! CreateDataPropertyOrThrow(nfOpts"numberingSystem"numberingSystem)。
  7. hoursStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumIntegerDigits"2𝔽)。
  8. signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"signDisplay""never")。
  9. 执行 ! CreateDataPropertyOrThrow(nfOpts"useGrouping"false)。
  10. nf 为 ! Construct(%Intl.NumberFormat%,« durationFormat.[[Locale]]nfOpts »)。
  11. hoursPartsPartitionNumberPattern(nfhoursValue)。
  12. hoursParts 的每个Record { [[Type]], [[Value]] } part,执行
    1. Record { [[Type]]: part.[[Type]][[Value]]: part.[[Value]][[Unit]]: "hour" } 追加至 result
  13. 返回 result

13.5.10 FormatNumericMinutes ( durationFormat, minutesValue, hoursDisplayed, signDisplayed )

抽象操作 FormatNumericMinutes 接受参数 durationFormat(一个 DurationFormat 对象)、minutesValue(一个整数)、hoursDisplayed(布尔值)与 signDisplayed(布尔值),并返回一个List(其元素为Records)。minutesValue 为一个表示分钟数的整数。该操作根据有效语言环境与 durationFormat 的格式化选项,为 minutesValue 生成分段。调用时执行以下步骤:

  1. result 为一个新的空List
  2. hoursDisplayedtrue,则
    1. separatordurationFormat.[[HourMinuteSeparator]]
    2. Record { [[Type]]: "literal", [[Value]]: separator, [[Unit]]: empty } 追加至 result
  3. minutesStyledurationFormat.[[MinutesOptions]].[[Style]]
  4. 断言minutesStyle"numeric"minutesStyle"2-digit"
  5. nfOptsOrdinaryObjectCreate(null)。
  6. numberingSystemdurationFormat.[[NumberingSystem]]
  7. 执行 ! CreateDataPropertyOrThrow(nfOpts"numberingSystem"numberingSystem)。
  8. minutesStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumIntegerDigits"2𝔽)。
  9. signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"signDisplay""never")。
  10. 执行 ! CreateDataPropertyOrThrow(nfOpts"useGrouping"false)。
  11. nf 为 ! Construct(%Intl.NumberFormat%,« durationFormat.[[Locale]]nfOpts »)。
  12. minutesPartsPartitionNumberPattern(nfminutesValue)。
  13. minutesParts 的每个Record { [[Type]], [[Value]] } part,执行
    1. Record { [[Type]]: part.[[Type]][[Value]]: part.[[Value]][[Unit]]: "minute" } 追加至 result
  14. 返回 result

13.5.11 FormatNumericSeconds ( durationFormat, secondsValue, minutesDisplayed, signDisplayed )

抽象操作 FormatNumericSeconds 接受参数 durationFormat(一个 DurationFormat 对象)、secondsValue(一个数学值)、minutesDisplayed(布尔值)与 signDisplayed(布尔值),并返回一个List(其元素为Records)。secondsValue 是一个表示秒数的数学值。该操作根据有效语言环境与 durationFormat 的格式化选项,为 secondsValue 生成分段。调用时执行以下步骤:

  1. result 为一个新的空List
  2. minutesDisplayedtrue,则
    1. separatordurationFormat.[[MinuteSecondSeparator]]
    2. Record { [[Type]]: "literal", [[Value]]: separator, [[Unit]]: empty } 追加至 result
  3. secondsStyledurationFormat.[[SecondsOptions]].[[Style]]
  4. 断言secondsStyle"numeric"secondsStyle"2-digit"
  5. nfOptsOrdinaryObjectCreate(null)。
  6. numberingSystemdurationFormat.[[NumberingSystem]]
  7. 执行 ! CreateDataPropertyOrThrow(nfOpts"numberingSystem"numberingSystem)。
  8. secondsStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumIntegerDigits"2𝔽)。
  9. signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"signDisplay""never")。
  10. 执行 ! CreateDataPropertyOrThrow(nfOpts"useGrouping"false)。
  11. fractionDigitsdurationFormat.[[FractionalDigits]]
  12. fractionDigitsundefined,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"maximumFractionDigits"9𝔽)。
    2. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumFractionDigits"+0𝔽)。
  13. 否则,
    1. 执行 ! CreateDataPropertyOrThrow(nfOpts"maximumFractionDigits"fractionDigits)。
    2. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumFractionDigits"fractionDigits)。
  14. 执行 ! CreateDataPropertyOrThrow(nfOpts"roundingMode""trunc")。
  15. nf 为 ! Construct(%Intl.NumberFormat%,« durationFormat.[[Locale]]nfOpts »)。
  16. secondsPartsPartitionNumberPattern(nfsecondsValue)。
  17. secondsParts 的每个Record { [[Type]], [[Value]] } part,执行
    1. Record { [[Type]]: part.[[Type]][[Value]]: part.[[Value]][[Unit]]: "second" } 追加至 result
  18. 返回 result

13.5.12 FormatNumericUnits ( durationFormat, duration, firstNumericUnit, signDisplayed )

抽象操作 FormatNumericUnits 接受参数 durationFormat(一个 DurationFormat 对象)、duration(一个Duration Record)、firstNumericUnit(字符串)与 signDisplayed(布尔值),并返回一个List(其元素为Records)。它根据有效语言环境与 durationFormat 的格式化选项,为 duration 中使用 "numeric""2-digit" 样式的各元素创建分段。调用时执行以下步骤:

  1. 断言firstNumericUnit"hours""minutes""seconds" 之一。
  2. numericPartsList 为一个新的空List
  3. hoursValueduration.[[Hours]]
  4. hoursDisplaydurationFormat.[[HoursOptions]].[[Display]]
  5. minutesValueduration.[[Minutes]]
  6. minutesDisplaydurationFormat.[[MinutesOptions]].[[Display]]
  7. secondsValueduration.[[Seconds]]
  8. duration.[[Milliseconds]] 非 0 或 duration.[[Microseconds]] 非 0 或 duration.[[Nanoseconds]] 非 0,则
    1. secondsValue 设为 secondsValue + ComputeFractionalDigits(durationFormatduration)。
  9. secondsDisplaydurationFormat.[[SecondsOptions]].[[Display]]
  10. hoursFormattedfalse
  11. firstNumericUnit"hours",则
    1. hoursValue 非 0 或 hoursDisplay"always",则
      1. hoursFormatted 设为 true
  12. secondsValue 非 0 或 secondsDisplay"always",则
    1. secondsFormattedtrue
  13. 否则,
    1. secondsFormattedfalse
  14. minutesFormattedfalse
  15. firstNumericUnit"hours"firstNumericUnit"minutes",则
    1. hoursFormattedtruesecondsFormattedtrue,则
      1. minutesFormatted 设为 true
    2. 否则若 minutesValue 非 0 或 minutesDisplay"always",则
      1. minutesFormatted 设为 true
  16. hoursFormattedtrue,则
    1. signDisplayedtrue,则
      1. hoursValue 为 0 且 DurationSign(duration) 为 -1,则
        1. hoursValue 设为 negative-zero
    2. hoursPartsFormatNumericHours(durationFormathoursValuesignDisplayed)。
    3. numericPartsList 设为 list-concatenation(numericPartsListhoursParts) 的结果。
    4. signDisplayed 设为 false
  17. minutesFormattedtrue,则
    1. signDisplayedtrue,则
      1. minutesValue 为 0 且 DurationSign(duration) 为 -1,则
        1. minutesValue 设为 negative-zero
    2. minutesPartsFormatNumericMinutes(durationFormatminutesValuehoursFormattedsignDisplayed)。
    3. numericPartsList 设为 list-concatenation(numericPartsListminutesParts) 的结果。
    4. signDisplayed 设为 false
  18. secondsFormattedtrue,则
    1. secondsPartsFormatNumericSeconds(durationFormatsecondsValueminutesFormattedsignDisplayed)。
    2. numericPartsList 设为 list-concatenation(numericPartsListsecondsParts) 的结果。
  19. 返回 numericPartsList

13.5.13 IsFractionalSecondUnitName ( unit )

抽象操作 IsFractionalSecondUnitName 接受参数 unit(字符串)并返回一个布尔值。调用时执行以下步骤:

  1. unit"milliseconds""microseconds""nanoseconds" 之一,返回 true
  2. 返回 false

13.5.14 ListFormatParts ( durationFormat, partitionedPartsList )

抽象操作 ListFormatParts 接受参数 durationFormat(一个 DurationFormat 对象)与 partitionedPartsList(一个由ListsRecords 组成的List),并返回一个List。它根据有效语言环境与 durationFormat 的格式化选项,创建与 partitionedPartsList 中各List 内的分段相对应的列表。调用时执行以下步骤:

  1. lfOptsOrdinaryObjectCreate(null)。
  2. 执行 ! CreateDataPropertyOrThrow(lfOpts"type""unit")。
  3. listStyledurationFormat.[[Style]]
  4. listStyle"digital",则
    1. listStyle 设为 "short"
  5. 执行 ! CreateDataPropertyOrThrow(lfOpts"style"listStyle)。
  6. lf 为 ! Construct(%Intl.ListFormat%,« durationFormat.[[Locale]]lfOpts »)。
  7. strings 为一个新的空List
  8. partitionedPartsList 的每个元素 parts,执行
    1. string 为空字符串。
    2. parts 中的每个Record { [[Type]], [[Value]], [[Unit]] } part,执行
      1. string 设为 字符串连接(stringpart.[[Value]]) 的结果。
    3. string 追加至 strings
  9. formattedPartsListCreatePartsFromList(lfstrings)。
  10. partitionedPartsIndex 为 0。
  11. partitionedLengthpartitionedPartsList 的元素个数。
  12. flattenedPartsList 为一个新的空List
  13. formattedPartsList 中的每个Record { [[Type]], [[Value]] } listPart,执行
    1. listPart.[[Type]]"element",则
      1. 断言partitionedPartsIndex < partitionedLength
      2. partspartitionedPartsList[partitionedPartsIndex]。
      3. parts 中的每个Record { [[Type]], [[Value]], [[Unit]] } part,执行
        1. part 追加至 flattenedPartsList
      4. partitionedPartsIndex 设为 partitionedPartsIndex + 1。
    2. 否则,
      1. 断言listPart.[[Type]]"literal"
      2. Record { [[Type]]: "literal", [[Value]]: listPart.[[Value]], [[Unit]]: empty } 追加至 flattenedPartsList
  14. 返回 flattenedPartsList

13.5.15 PartitionDurationFormatPattern ( durationFormat, duration )

抽象操作 PartitionDurationFormatPattern 接受参数 durationFormat(一个 DurationFormat)与 duration(一个Duration Record),并返回一个List。它根据有效语言环境与 durationFormat 的格式化选项,为 duration 创建对应的分段。调用时执行以下步骤:

  1. result 为一个新的空List
  2. signDisplayedtrue
  3. numericUnitFoundfalse
  4. numericUnitFoundfalse 时,按表序对 表 24(除表头行)逐行执行:
    1. valueduration 中名为当前行 Value Field 值的字段之值。
    2. unitOptionsdurationFormat 中名为当前行 Internal Slot 值的内部槽的值。
    3. styleunitOptions.[[Style]]
    4. displayunitOptions.[[Display]]
    5. unit 为当前行 Unit 列的值。
    6. numberFormatUnit 为当前行 NumberFormat Unit 列的值。
    7. style"numeric""2-digit",则
      1. numericPartsListFormatNumericUnits(durationFormatdurationunitsignDisplayed)。
      2. numericPartsList 非空,将 numericPartsList 追加至 result
      3. numericUnitFound 设为 true
    8. 否则,
      1. nfOptsOrdinaryObjectCreate(null)。
      2. NextUnitFractional(durationFormatunit) 为 true,则
        1. value 设为 value + ComputeFractionalDigits(durationFormatduration)。
        2. fractionDigitsdurationFormat.[[FractionalDigits]]
        3. fractionDigitsundefined,则
          1. 执行 ! CreateDataPropertyOrThrow(nfOpts"maximumFractionDigits"9𝔽)。
          2. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumFractionDigits"+0𝔽)。
        4. 否则,
          1. 执行 ! CreateDataPropertyOrThrow(nfOpts"maximumFractionDigits"fractionDigits)。
          2. 执行 ! CreateDataPropertyOrThrow(nfOpts"minimumFractionDigits"fractionDigits)。
        5. 执行 ! CreateDataPropertyOrThrow(nfOpts"roundingMode""trunc")。
        6. numericUnitFound 设为 true
      3. display"always"value 非 0,则
        1. 执行 ! CreateDataPropertyOrThrow(nfOpts"numberingSystem"durationFormat.[[NumberingSystem]])。
        2. signDisplayedtrue,则
          1. signDisplayed 设为 false
          2. value 为 0 且 DurationSign(duration) 为 -1,将 value 设为 negative-zero
        3. 否则,
          1. 执行 ! CreateDataPropertyOrThrow(nfOpts"signDisplay""never")。
        4. 执行 ! CreateDataPropertyOrThrow(nfOpts"style""unit")。
        5. 执行 ! CreateDataPropertyOrThrow(nfOpts"unit"numberFormatUnit)。
        6. 执行 ! CreateDataPropertyOrThrow(nfOpts"unitDisplay"style)。
        7. nf 为 ! Construct(%Intl.NumberFormat%, « durationFormat.[[Locale]]nfOpts »)。
        8. partsPartitionNumberPattern(nfvalue)。
        9. list 为一个新的空List
        10. parts 的每个Record { [[Type]], [[Value]] } part,执行
          1. Record { [[Type]]: part.[[Type]][[Value]]: part.[[Value]][[Unit]]: numberFormatUnit } 追加至 list
        11. list 追加至 result
  5. 返回 ListFormatParts(durationFormatresult)。
表 24:与 PartitionDurationFormatPattern 相关的 DurationFormat 实例内部槽与属性
值字段 内部槽 单位 NumberFormat 单位
[[Years]] [[YearsOptions]] "years" "year"
[[Months]] [[MonthsOptions]] "months" "month"
[[Weeks]] [[WeeksOptions]] "weeks" "week"
[[Days]] [[DaysOptions]] "days" "day"
[[Hours]] [[HoursOptions]] "hours" "hour"
[[Minutes]] [[MinutesOptions]] "minutes" "minute"
[[Seconds]] [[SecondsOptions]] "seconds" "second"
[[Milliseconds]] [[MillisecondsOptions]] "milliseconds" "millisecond"
[[Microseconds]] [[MicrosecondsOptions]] "microseconds" "microsecond"
[[Nanoseconds]] [[NanosecondsOptions]] "nanoseconds" "nanosecond"

14 ListFormat 对象

14.1 Intl.ListFormat 构造函数

Intl.ListFormat 构造函数

  • %Intl.ListFormat%
  • Intl 对象"ListFormat" 属性的初始值。

服务构造函数作为 Intl 对象属性的通用行为,见 9.1

14.1.1 Intl.ListFormat ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.ListFormat 函数时,执行以下步骤:

  1. 如果 NewTarget 为 undefined,则抛出 TypeError 异常。
  2. listFormat 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.ListFormat.prototype%",« [[InitializedListFormat]][[Locale]][[Type]][[Style]][[Templates]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.ListFormat%%Intl.ListFormat%.[[LocaleData]]localesoptions)。
  4. options 设为 optionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. listFormat.[[Locale]] 设为 r.[[Locale]]
  7. type 为 ? GetOption(options"type"string,« "conjunction""disjunction""unit" »,"conjunction")。
  8. listFormat.[[Type]] 设为 type
  9. style 为 ? GetOption(options"style"string,« "long""short""narrow" », "long")。
  10. listFormat.[[Style]] 设为 style
  11. resolvedLocaleDatar.[[LocaleData]]
  12. dataLocaleTypesresolvedLocaleData.[[<type>]]。
  13. listFormat.[[Templates]] 设为 dataLocaleTypes.[[<style>]]。
  14. 返回 listFormat

14.2 Intl.ListFormat 构造函数的属性

Intl.ListFormat 构造函数

14.2.1 Intl.ListFormat.prototype

Intl.ListFormat.prototype 的值为 %Intl.ListFormat.prototype%

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

14.2.2 Intl.ListFormat.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行以下步骤:

  1. availableLocales%Intl.ListFormat%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocalesrequestedLocalesoptions)。

14.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 实现自定义 的前提下,受 9.1 的约束。

[[RelevantExtensionKeys]] 内部槽的值为 « »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « »。

注 1
Intl.ListFormat 没有任何相关的扩展键。

[[LocaleData]] 内部槽的值在 实现自定义 的前提下,受 9.1 以及以下附加约束的限制,对 %Intl.ListFormat%.[[AvailableLocales]] 中每个语言环境值 locale

  • [[LocaleData]].[[<locale>]] 是一个 Record, 具有三个字段 [[conjunction]][[disjunction]][[unit]]。每个字段的值都是一个 Record,并且必须具有三种格式化样式为名的字段:[[long]][[short]][[narrow]]
  • 上述各字段均视为一个ListFormat 模板集,其值必须是一个 List, 列表元素为具有字段名 [[Pair]][[Start]][[Middle]][[End]]Records。这些字段的值必须为 LDML List Format Rules 中规定的模板字符串。每个模板字符串必须且仅一次包含子串 "{0}""{1}"子串 "{0}" 应当出现在 子串 "{1}" 之前。
注 2
建议实现使用通用语言环境数据存储库(CLDR,https://cldr.unicode.org/)提供的语言环境数据。在 LDML 的 listPattern 中,conjunction 对应 “standard”,disjunction 对应 “or”,unit 对应 “unit”。
注 3
在列表类型中,conjunction 表示基于 “and” 的列表(例如 “A, B, and C”),disjunction 表示基于 “or” 的列表(例如 “A, B, or C”),而 unit 表示带单位的值列表(例如 “5 pounds, 12 ounces”)。

14.3 Intl.ListFormat 原型对象的属性

Intl.ListFormat 原型对象

  • %Intl.ListFormat.prototype%
  • 是一个普通对象
  • 不是 Intl.ListFormat 实例,且不具有 [[InitializedListFormat]] 内部槽,也不具有 Intl.ListFormat 实例对象的其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

14.3.1 Intl.ListFormat.prototype.constructor

Intl.ListFormat.prototype.constructor 的初始值为 %Intl.ListFormat%

14.3.2 Intl.ListFormat.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境与选项。

  1. lfthis 值。
  2. 执行 ? RequireInternalSlot(lf[[InitializedListFormat]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序,对 表 25 的每一行(除表头行)执行:
    1. p 为当前行的 Property 值。
    2. vlf 内部槽中名称为当前行 Internal Slot 值的槽的值。
    3. 断言vundefined
    4. 执行 ! CreateDataPropertyOrThrow(optionspv)。
  5. 返回 options
表 25:ListFormat 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[Type]] "type"
[[Style]] "style"

14.3.3 Intl.ListFormat.prototype.format ( list )

当以参数 list 调用 format 方法时,执行以下步骤:

  1. lfthis 值。
  2. 执行 ? RequireInternalSlot(lf[[InitializedListFormat]])。
  3. stringList 为 ? StringListFromIterable(list)。
  4. 返回 FormatList(lfstringList)。

14.3.4 Intl.ListFormat.prototype.formatToParts ( list )

当以参数 list 调用 formatToParts 方法时,执行以下步骤:

  1. lfthis 值。
  2. 执行 ? RequireInternalSlot(lf[[InitializedListFormat]])。
  3. stringList 为 ? StringListFromIterable(list)。
  4. 返回 FormatListToParts(lfstringList)。

14.3.5 Intl.ListFormat.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.ListFormat"

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

14.4 Intl.ListFormat 实例的属性

Intl.ListFormat 实例从 %Intl.ListFormat.prototype% 继承属性。

Intl.ListFormat 实例具有一个 [[InitializedListFormat]] 内部槽。

Intl.ListFormat 实例还具有若干由 Intl.ListFormat 构造函数 计算得到的内部槽:

  • [[Locale]] 为字符串值,表示其本地化被列表格式样式使用的语言环境的 语言标签
  • [[Type]] 为字符串值 "conjunction""disjunction""unit" 之一,标识所使用的列表类型。
  • [[Style]] 为字符串值 "long""short""narrow" 之一,标识所用的列表格式样式。
  • [[Templates]] 为一个 ListFormat 模板集

14.5 ListFormat 对象的抽象操作

14.5.1 DeconstructPattern ( patternplaceables )

抽象操作 DeconstructPattern 接受参数 pattern(一个 Pattern String)与 placeables(一个 Record),并返回一个 List

它将模式字符串分解为一个由各部分组成的 List

placeables 是一个 Record, 其键为模式字符串中使用的占位符记号,值为用于结果 List 表示该记号部分的分段 Records (如由 PartitionPattern 产生)。示例:

输入:
  DeconstructPattern("AA{xx}BB{yy}CC", {
    [[xx]]: {[[Type]]: "hour", [[Value]]: "15"},
    [[yy]]: {[[Type]]: "minute", [[Value]]: "06"}
  })

输出(分段 Record 列表):
  «
    {[[Type]]: "literal", [[Value]]: "AA"},
    {[[Type]]: "hour", [[Value]]: "15"},
    {[[Type]]: "literal", [[Value]]: "BB"},
    {[[Type]]: "minute", [[Value]]: "06"},
    {[[Type]]: "literal", [[Value]]: "CC"}
  »
          

调用时执行以下步骤:

  1. patternPartsPartitionPattern(pattern)。
  2. result 为一个新的空 List
  3. patternParts 中的每个 Record { [[Type]][[Value]]  } patternPart,执行:
    1. partpatternPart.[[Type]]
    2. part"literal",则
      1. Record { [[Type]]: "literal"[[Value]]: patternPart.[[Value]] } 追加到 result
    3. 否则,
      1. 断言placeables 具有字段 [[<part>]]。
      2. substplaceables.[[<part>]]。
      3. subst 是一个 List,则
        1. subst 的每个元素 s,执行:
          1. s 追加到 result
      4. 否则,
        1. subst 追加到 result
  4. 返回 result

14.5.2 CreatePartsFromList ( listFormat, list )

抽象操作 CreatePartsFromList 接受参数 listFormat(一个 Intl.ListFormat)与 list(一个由字符串构成的 List),并返回一个 List, 其中元素是带有字段 [[Type]]"element""literal")与 [[Value]](字符串)的 Records。它根据有效语言环境与 listFormat 的格式化选项创建相应的分段列表。调用时执行以下步骤:

  1. sizelist 的元素个数。
  2. size 为 0,则
    1. 返回一个新的空 List
  3. size 为 2,则
    1. n 为基于 listFormat.[[Locale]]list[0] 与 list[1] 对 listFormat.[[Templates]] 的索引。
    2. patternlistFormat.[[Templates]][n].[[Pair]]
    3. firstRecord { [[Type]]: "element"[[Value]]: list[0] }。
    4. secondRecord { [[Type]]: "element"[[Value]]: list[1] }。
    5. placeablesRecord { [[0]]: first[[1]]: second }。
    6. 返回 DeconstructPattern(patternplaceables)。
  4. lastRecord { [[Type]]: "element"[[Value]]: list[size - 1] }。
  5. parts 为 « last »。
  6. isize - 2。
  7. i ≥ 0 时重复:
    1. headRecord { [[Type]]: "element"[[Value]]: list[i] }。
    2. n 为一个 实现自定义 的索引,索引到 listFormat.[[Templates]],基于 listFormat.[[Locale]]headparts
    3. 如果 i 为 0,则
      1. patternlistFormat.[[Templates]][n].[[Start]]
    4. 否则若 i 小于 size - 2,则
      1. patternlistFormat.[[Templates]][n].[[Middle]]
    5. 否则,
      1. patternlistFormat.[[Templates]][n].[[End]]
    6. placeablesRecord { [[0]]: head[[1]]: parts }。
    7. parts 设为 DeconstructPattern(patternplaceables) 的结果。
    8. i 减 1。
  8. 返回 parts
用于在多个模板之间选择的索引 n 允许连接词依赖于上下文,例如在西班牙语中,可能根据后续单词选择 “y” 或 “e”。

14.5.3 FormatList ( listFormat, list )

抽象操作 FormatList 接受参数 listFormat(一个 Intl.ListFormat)与 list(一个由字符串构成的 List),并返回一个字符串。调用时执行以下步骤:

  1. partsCreatePartsFromList(listFormatlist)。
  2. result 为空字符串。
  3. parts 的每个 Record { [[Type]][[Value]]  } part,执行:
    1. result 设为 resultpart.[[Value]]字符串连接
  4. 返回 result

14.5.4 FormatListToParts ( listFormat, list )

抽象操作 FormatListToParts 接受参数 listFormat(一个 Intl.ListFormat)与 list(一个由字符串构成的 List),并返回一个数组。调用时执行以下步骤:

  1. partsCreatePartsFromList(listFormatlist)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]][[Value]]  } part,执行:
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(O"type"part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(O"value"part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O)。
    5. n 加 1。
  5. 返回 result

14.5.5 StringListFromIterable ( iterable )

抽象操作 StringListFromIterable 接受参数 iterable(一个ECMAScript 语言值),并返回一个正常完成,包含由字符串构成的 List,或一个抛出完成。调用时执行以下步骤:

  1. iterableundefined,则
    1. 返回一个新的空 List
  2. iteratorRecord 为 ? GetIterator(iterablesync)。
  3. list 为一个新的空 List
  4. 重复:
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. nextdone,则
      1. 返回 list
    3. next 不是字符串,则
      1. errorThrowCompletion(一个新创建的 TypeError 对象)。
      2. 返回 ? IteratorClose(iteratorRecorderror)。
    4. next 追加到 list

该算法在遇到非字符串值时会抛出异常,因为对于任意值不存在明显的、面向语言环境的强制转换方式。

15 Locale 对象

15.1 Intl.Locale 构造函数

Intl.Locale 构造函数

  • %Intl.Locale%
  • Intl 对象"Locale" 属性的初始值。

15.1.1 Intl.Locale ( tag [ , options ] )

当以参数 tag 与可选参数 options 调用 Intl.Locale 函数时,执行以下步骤:

  1. 如果 NewTarget 为 undefined,则抛出 TypeError 异常。
  2. localeExtensionKeys%Intl.Locale%.[[LocaleExtensionKeys]]
  3. internalSlotsList 为 « [[InitializedLocale]][[Locale]][[Calendar]][[Collation]][[HourCycle]][[NumberingSystem]] »。
  4. localeExtensionKeys 包含 "kf",则
    1. [[CaseFirst]] 追加至 internalSlotsList
  5. localeExtensionKeys 包含 "kn",则
    1. [[Numeric]] 追加至 internalSlotsList
  6. locale 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.Locale.prototype%"internalSlotsList)。
  7. 如果 tag 不是字符串tag 不是对象,则抛出 TypeError 异常。
  8. 如果 tag 是对象且具有 [[InitializedLocale]] 内部槽,则
    1. tagtag.[[Locale]]
  9. 否则,
    1. tag 为 ? ToString(tag)。
  10. options 设为 ? CoerceOptionsToObject(options)。
  11. IsStructurallyValidLanguageTag(tag) 为 false,则抛出 RangeError 异常。
  12. tag 设为 CanonicalizeUnicodeLocaleId(tag)。
  13. tag 设为 ? UpdateLanguageId(tagoptions)。
  14. opt 为一个新的 Record
  15. calendar 为 ? GetOption(options"calendar"stringemptyundefined)。
  16. calendarundefined,则
    1. calendar 不能被 type Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  17. opt.[[ca]] 设为 calendar
  18. collation 为 ? GetOption(options"collation"stringemptyundefined)。
  19. collationundefined,则
    1. collation 不能被 type Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  20. opt.[[co]] 设为 collation
  21. hc 为 ? GetOption(options"hourCycle"string,« "h11""h12""h23""h24" »,undefined)。
  22. opt.[[hc]] 设为 hc
  23. kf 为 ? GetOption(options"caseFirst"string,« "upper""lower""false" »,undefined)。
  24. opt.[[kf]] 设为 kf
  25. kn 为 ? GetOption(options"numeric"booleanemptyundefined)。
  26. knundefined,将 kn 设为 ! ToString(kn)。
  27. opt.[[kn]] 设为 kn
  28. numberingSystem 为 ? GetOption(options"numberingSystem"stringemptyundefined)。
  29. numberingSystemundefined,则
    1. numberingSystem 不能被 type Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  30. opt.[[nu]] 设为 numberingSystem
  31. rMakeLocaleRecord(tagoptlocaleExtensionKeys)。
  32. locale.[[Locale]] 设为 r.[[locale]]
  33. locale.[[Calendar]] 设为 r.[[ca]]
  34. locale.[[Collation]] 设为 r.[[co]]
  35. locale.[[HourCycle]] 设为 r.[[hc]]
  36. localeExtensionKeys 包含 "kf",则
    1. locale.[[CaseFirst]] 设为 r.[[kf]]
  37. localeExtensionKeys 包含 "kn",则
    1. SameValue(r.[[kn]]"true") 为 true,或 r.[[kn]] 为空字符串,则
      1. locale.[[Numeric]] 设为 true
    2. 否则,
      1. locale.[[Numeric]] 设为 false
  38. locale.[[NumberingSystem]] 设为 r.[[nu]]
  39. 返回 locale

15.1.2 UpdateLanguageId ( tag, options )

抽象操作 UpdateLanguageId 接受参数 tag(一个 Unicode 规范化的语言环境标识符)与 options(一个对象),并返回一个正常完成,包含一个 语言标签,或一个抛出完成。它根据 options 的相应属性更新 tag 中的 unicode_language_id 子标签,并返回结构上有效但未规范化的结果。调用时执行以下步骤:

  1. baseNameGetLocaleBaseName(tag)。
  2. language 为 ? GetOption(options"language"stringemptyGetLocaleLanguage(baseName))。
  3. language 不能被 unicode_language_subtag Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  4. script 为 ? GetOption(options"script"stringemptyGetLocaleScript(baseName))。
  5. scriptundefined,则
    1. script 不能被 unicode_script_subtag Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  6. region 为 ? GetOption(options"region"stringemptyGetLocaleRegion(baseName))。
  7. regionundefined,则
    1. region 不能被 unicode_region_subtag Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
  8. variants 为 ? GetOption(options"variants"stringemptyGetLocaleVariants(baseName))。
  9. variantsundefined,则
    1. variants 为空字符串,则抛出 RangeError 异常。
    2. lowerVariantsASCII-lowercase(variants)。
    3. variantSubtagsStringSplitToList(lowerVariants"-")。
    4. variantSubtags 的每个元素 variant,执行:
      1. variant 不能被 unicode_variant_subtag Unicode locale nonterminal 匹配,则抛出 RangeError 异常。
    5. variantSubtags 包含任一重复元素,则抛出 RangeError 异常。
  10. allExtensionstagbaseName 之后的后缀。
  11. newTaglanguage
  12. scriptundefined,将 newTag 设为 字符串连接(newTag"-"script)。
  13. regionundefined,将 newTag 设为 字符串连接(newTag"-"region)。
  14. variantsundefined,将 newTag 设为 字符串连接(newTag"-"variants)。
  15. newTag 设为 字符串连接(newTagallExtensions) 的结果。
  16. 返回 newTag

15.1.3 MakeLocaleRecord ( tag, optionslocaleExtensionKeys )

抽象操作 MakeLocaleRecord 接受参数 tag(一个 语言标签)、options(一个 Record)与 localeExtensionKeys(一个由字符串构成的 List),并返回一个 Record。 它构造并返回一个 Record,其中 localeExtensionKeys 的每个元素都定义了一个对应字段,其数据来自 tag 的任意 Unicode 语言环境扩展序列,并被 options 的对应字段覆盖;另外还包含一个 [[locale]] 字段,其值为将这些字段并入 tag 后得到的 Unicode 规范化语言环境标识符。调用时执行以下步骤:

  1. 如果 tag 包含作为 Unicode 语言环境扩展序列substring,则
    1. extension 为该 Unicode 语言环境扩展序列tag 中对应的 substring 的字符串值。
    2. componentsUnicodeExtensionComponents(extension)。
    3. attributescomponents.[[Attributes]]
    4. keywordscomponents.[[Keywords]]
  2. 否则,
    1. attributes 为一个新的空 List
    2. keywords 为一个新的空 List
  3. result 为一个新的 Record
  4. localeExtensionKeys 的每个元素 key,执行:
    1. 如果 keywords 包含一个 [[Key]]key 的元素,则
      1. entrykeywords[[Key]]key 的元素。
      2. valueentry.[[Value]]
    2. 否则,
      1. entryempty
      2. valueundefined
    3. 断言options 具有字段 [[<key>]]。
    4. overrideValueoptions.[[<key>]]。
    5. overrideValueundefined,则
      1. value 设为 CanonicalizeUValue(keyoverrideValue)。
      2. entryempty,则
        1. entry.[[Value]] 设为 value
      3. 否则,
        1. Record { [[Key]]: key[[Value]]: value } 追加至 keywords
    6. result.[[<key>]] 设为 value
  5. locale 为从 tag 中移除所有 Unicode 语言环境扩展序列 后得到的字符串值。
  6. attributes 非空或 keywords 非空,则
    1. result.[[locale]] 设为 InsertUnicodeExtensionAndCanonicalize(localeattributeskeywords)。
  7. 否则,
    1. result.[[locale]] 设为 CanonicalizeUnicodeLocaleId(locale)。
  8. 返回 result

15.2 Intl.Locale 构造函数的属性

Intl.Locale 构造函数

15.2.1 Intl.Locale.prototype

Intl.Locale.prototype 的值为 %Intl.Locale.prototype%

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

15.2.2 内部槽

[[LocaleExtensionKeys]] 内部槽的值是一个 List, 必须包含 « "ca""co""hc""nu" » 的所有元素,并且还必须包含 « "kf""kn" » 中的任意元素,只要它同时也是 %Intl.Collator%.[[RelevantExtensionKeys]] 的元素,且不得包含其他任何元素。

15.3 Intl.Locale 原型对象的属性

Intl.Locale 原型对象

  • %Intl.Locale.prototype%
  • 是一个普通对象
  • 不是 Intl.Locale 实例,且不具有 [[InitializedLocale]] 内部槽,也不具有 Intl.Locale 实例对象的其他内部槽。
  • [[Prototype]] 内部槽的值为 %Object.prototype%

15.3.1 Intl.Locale.prototype.constructor

Intl.Locale.prototype.constructor 的初始值为 %Intl.Locale%

15.3.2 get Intl.Locale.prototype.baseName

Intl.Locale.prototype.baseName 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 GetLocaleBaseName(loc.[[Locale]])。

15.3.3 get Intl.Locale.prototype.calendar

Intl.Locale.prototype.calendar 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[Calendar]]

15.3.4 get Intl.Locale.prototype.caseFirst

仅当 %Intl.Locale%.[[LocaleExtensionKeys]] 包含 "kf" 时,此属性才存在。

Intl.Locale.prototype.caseFirst 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[CaseFirst]]

15.3.5 get Intl.Locale.prototype.collation

Intl.Locale.prototype.collation 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[Collation]]

15.3.6 get Intl.Locale.prototype.hourCycle

Intl.Locale.prototype.hourCycle 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[HourCycle]]

15.3.7 get Intl.Locale.prototype.language

Intl.Locale.prototype.language 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 GetLocaleLanguage(loc.[[Locale]])。

15.3.8 Intl.Locale.prototype.maximize ( )

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. maximal 为将 Add Likely Subtags 算法应用于 loc.[[Locale]] 的结果。若出现错误,则将 maximal 设为 loc.[[Locale]]
  4. 返回 ! Construct(%Intl.Locale%maximal)。

15.3.9 Intl.Locale.prototype.minimize ( )

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. minimal 为将 Remove Likely Subtags 算法应用于 loc.[[Locale]] 的结果。若出现错误,则将 minimal 设为 loc.[[Locale]]
  4. 返回 ! Construct(%Intl.Locale%minimal)。

15.3.10 get Intl.Locale.prototype.numberingSystem

Intl.Locale.prototype.numberingSystem 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[NumberingSystem]]

15.3.11 get Intl.Locale.prototype.numeric

仅当 %Intl.Locale%.[[LocaleExtensionKeys]] 包含 "kn" 时,此属性才存在。

Intl.Locale.prototype.numeric 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[Numeric]]

15.3.12 get Intl.Locale.prototype.region

Intl.Locale.prototype.region 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 GetLocaleRegion(loc.[[Locale]])。

15.3.13 get Intl.Locale.prototype.script

Intl.Locale.prototype.script 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 GetLocaleScript(loc.[[Locale]])。

15.3.14 Intl.Locale.prototype.toString ( )

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 loc.[[Locale]]

15.3.15 get Intl.Locale.prototype.variants

Intl.Locale.prototype.variants 是一个访问器属性,其 setter 为 undefined。其 getter 执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc[[InitializedLocale]])。
  3. 返回 GetLocaleVariants(loc.[[Locale]])。

15.3.16 Intl.Locale.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.Locale"

此属性具有如下特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

15.4 Intl.Locale 实例的属性

Intl.Locale 实例是普通对象,并从 %Intl.Locale.prototype% 继承属性。

Intl.Locale 实例具有 [[InitializedLocale]] 内部槽。

Intl.Locale 实例还具有若干由 Intl.Locale 构造函数 计算得到的内部槽:

  • [[Locale]] 为字符串值,表示用于格式化的语言环境的 语言标签
  • [[Calendar]] 要么为 undefined,要么为一个字符串值,且是规范形式的 Unicode 日历标识符
  • [[Collation]] 要么为 undefined,要么为一个字符串值,且是规范形式的 Unicode 排序规则标识符
  • [[HourCycle]] 要么为 undefined,要么为一个字符串值,且是规范形式的 Unicode 小时制标识符
  • [[NumberingSystem]] 要么为 undefined,要么为一个字符串值,且是规范形式的 Unicode 数字系统标识符
  • [[CaseFirst]] 要么为 undefined,要么为字符串值 "upper""lower""false" 之一。仅当 %Intl.Locale%[[LocaleExtensionKeys]] 内部槽包含 "kf" 时,该内部槽存在。
  • [[Numeric]] 要么为 undefined,要么为布尔值,指定该语言环境是否使用数字排序。仅当 %Intl.Locale%[[LocaleExtensionKeys]] 内部槽包含 "kn" 时,该内部槽存在。

15.5 Locale 对象的抽象操作

15.5.1 GetLocaleBaseName ( locale )

抽象操作 GetLocaleBaseName 接受参数 locale(字符串),并返回一个字符串。调用时执行以下步骤:

  1. 断言locale 可被 unicode_locale_id Unicode locale nonterminal 匹配。
  2. 返回 locale 的由 unicode_language_id Unicode locale nonterminal 匹配的最长前缀。

15.5.2 GetLocaleLanguage ( locale )

抽象操作 GetLocaleLanguage 接受参数 locale(字符串),并返回一个字符串。调用时执行以下步骤:

  1. baseNameGetLocaleBaseName(locale)。
  2. 断言baseName 的第一个 子标签 可被 unicode_language_subtag Unicode locale nonterminal 匹配。
  3. 返回 baseName 的第一个 子标签

15.5.3 GetLocaleScript ( locale )

抽象操作 GetLocaleScript 接受参数 locale(字符串),并返回一个字符串或 undefined。调用时执行以下步骤:

  1. baseNameGetLocaleBaseName(locale)。
  2. 断言baseName 最多包含一个可被 unicode_script_subtag Unicode locale nonterminal 匹配的 子标签
  3. 如果 baseName 包含一个可被 unicode_script_subtag Unicode locale nonterminal 匹配的 子标签,则返回该 子标签
  4. 返回 undefined

15.5.4 GetLocaleRegion ( locale )

抽象操作 GetLocaleRegion 接受参数 locale(字符串),并返回一个字符串或 undefined。调用时执行以下步骤:

  1. baseNameGetLocaleBaseName(locale)。
  2. 注:unicode_region_subtag 子标签 仅在首个 unicode_language_subtag 子标签 之后的位置有效,中间可选一个 unicode_script_subtag 子标签。在该位置,unicode_region_subtag 不会与任何其他有效的 子标签 混淆,因为它们的产生式彼此互斥。
  3. 断言baseName 的第一个 子标签 可被 unicode_language_subtag Unicode locale nonterminal 匹配。
  4. baseNameTailbaseName 在第一个 子标签 之后的后缀。
  5. 断言baseNameTail 最多包含一个可被 unicode_region_subtag Unicode locale nonterminal 匹配的 子标签
  6. 如果 baseNameTail 包含一个可被 unicode_region_subtag Unicode locale nonterminal 匹配的 子标签,则返回该 子标签
  7. 返回 undefined

15.5.5 GetLocaleVariants ( locale )

抽象操作 GetLocaleVariants 接受参数 locale(字符串),并返回一个字符串或 undefined。调用时执行以下步骤:

  1. baseNameGetLocaleBaseName(locale)。
  2. 注:baseName 中每个由 "-" 前缀的 子标签 要么是 unicode_script_subtagunicode_region_subtag,要么是 unicode_variant_subtag;但任何由 unicode_variant_subtag 匹配的 substring 都严格长于其可能同时被其他产生式匹配的任何前缀。
  3. variantsbaseName 的最长后缀,其以 "-" 开始,后随一个可被 unicode_variant_subtag Unicode locale nonterminal 匹配的 substring。若不存在此类后缀,则返回 undefined
  4. 返回 子串(variants,从 1 开始)。

16 NumberFormat 对象

16.1 Intl.NumberFormat 构造函数

Intl.NumberFormat 构造函数

  • %Intl.NumberFormat%
  • Intl 对象"NumberFormat" 属性的初始值。

服务构造函数作为 Intl 对象属性的通用行为,见 9.1

16.1.1 Intl.NumberFormat ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.NumberFormat 函数时,执行以下步骤:

  1. 如果 NewTarget 为 undefined,则令 newTarget活动函数对象,否则令 newTarget 为 NewTarget。
  2. numberFormat 为 ? OrdinaryCreateFromConstructor(newTarget"%Intl.NumberFormat.prototype%",« [[InitializedNumberFormat]][[Locale]][[LocaleData]][[NumberingSystem]][[Style]][[Unit]][[UnitDisplay]][[Currency]][[CurrencyDisplay]][[CurrencySign]][[MinimumIntegerDigits]][[MinimumFractionDigits]][[MaximumFractionDigits]][[MinimumSignificantDigits]][[MaximumSignificantDigits]][[RoundingType]][[Notation]][[CompactDisplay]][[UseGrouping]][[SignDisplay]][[RoundingIncrement]][[RoundingMode]][[ComputedRoundingPriority]][[TrailingZeroDisplay]][[BoundFormat]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.NumberFormat%%Intl.NumberFormat%.[[LocaleData]]localesoptions,« coerce-options »)。
  4. options 设为 optionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. numberFormat.[[Locale]] 设为 r.[[Locale]]
  7. numberFormat.[[LocaleData]] 设为 r.[[LocaleData]]
  8. numberFormat.[[NumberingSystem]] 设为 r.[[nu]]
  9. 执行 ? SetNumberFormatUnitOptions(numberFormatoptions)。
  10. stylenumberFormat.[[Style]]
  11. notation 为 ? GetOption(options"notation"string,« "standard""scientific""engineering""compact" », "standard")。
  12. numberFormat.[[Notation]] 设为 notation
  13. 如果 style"currency"notation"standard",则
    1. currencynumberFormat.[[Currency]]
    2. cDigitsCurrencyDigits(currency)。
    3. mnfdDefaultcDigits
    4. mxfdDefaultcDigits
  14. 否则,
    1. mnfdDefault 为 0。
    2. 如果 style"percent",则
      1. mxfdDefault 为 0。
    3. 否则,
      1. mxfdDefault 为 3。
  15. 执行 ? SetNumberFormatDigitOptions(numberFormatoptionsmnfdDefaultmxfdDefaultnotation)。
  16. compactDisplay 为 ? GetOption(options"compactDisplay"string,« "short""long" », "short")。
  17. defaultUseGrouping"auto"
  18. 如果 notation"compact",则
    1. numberFormat.[[CompactDisplay]] 设为 compactDisplay
    2. defaultUseGrouping 设为 "min2"
  19. 注:出于历史原因,字符串 "true""false" 被接受并替换为默认值。
  20. useGrouping 为 ? GetBooleanOrStringNumberFormatOption(options"useGrouping",« "min2""auto""always""true""false" »,defaultUseGrouping)。
  21. 如果 useGrouping"true"useGrouping"false",则将 useGrouping 设为 defaultUseGrouping
  22. 如果 useGroupingtrue,则将 useGrouping 设为 "always"
  23. numberFormat.[[UseGrouping]] 设为 useGrouping
  24. signDisplay 为 ? GetOption(options"signDisplay"string,« "auto""never""always""exceptZero""negative" », "auto")。
  25. numberFormat.[[SignDisplay]] 设为 signDisplay
  26. 如果实现支持 构造函数的规范可选模式 4.3 注 1,则
    1. thisthis 值。
    2. 返回 ? ChainNumberFormat(numberFormat, NewTarget,this)。
  27. 返回 numberFormat

16.1.1.1 ChainNumberFormat ( numberFormatnewTargetthis )

抽象操作 ChainNumberFormat 接受参数 numberFormat(一个 Intl.NumberFormat)、newTarget(一个ECMAScript 语言值)、this(一个ECMAScript 语言值),并返回一个正常完成,包含对象或一个抛出完成。调用时执行以下步骤:

  1. 如果 newTargetundefined 且 ? OrdinaryHasInstance(%Intl.NumberFormat%this) 为 true,则
    1. 执行 ? DefinePropertyOrThrow(this%Intl%.[[FallbackSymbol]],PropertyDescriptor{ [[Value]]: numberFormat[[Writable]]: false[[Enumerable]]: false[[Configurable]]: false })。
    2. 返回 this
  2. 返回 numberFormat

16.1.2 SetNumberFormatDigitOptions ( intlObjoptionsmnfdDefaultmxfdDefaultnotation )

抽象操作 SetNumberFormatDigitOptions 接受参数 intlObj(一个对象)、options(一个对象)、mnfdDefault(一个整数)、mxfdDefault(一个整数)、notation(一个字符串),并返回一个正常完成,包含unused或一个抛出完成。该操作填充 intlObj 影响与语言环境无关的数字舍入的内部槽(见 16.5.3)。调用时执行以下步骤:

  1. mnid 为 ? GetNumberOption(options"minimumIntegerDigits,",1,21,1)。
  2. mnfd 为 ? Get(options"minimumFractionDigits")。
  3. mxfd 为 ? Get(options"maximumFractionDigits")。
  4. mnsd 为 ? Get(options"minimumSignificantDigits")。
  5. mxsd 为 ? Get(options"maximumSignificantDigits")。
  6. intlObj.[[MinimumIntegerDigits]] 设为 mnid
  7. roundingIncrement 为 ? GetNumberOption(options"roundingIncrement",1,5000,1)。
  8. 如果 roundingIncrement 不属于 « 1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000 »,则抛出 RangeError 异常。
  9. roundingMode 为 ? GetOption(options"roundingMode"string,« "ceil""floor""expand""trunc""halfCeil""halfFloor""halfExpand""halfTrunc""halfEven" », "halfExpand")。
  10. roundingPriority 为 ? GetOption(options"roundingPriority"string,« "auto""morePrecision""lessPrecision" »,"auto")。
  11. trailingZeroDisplay 为 ? GetOption(options"trailingZeroDisplay"string,« "auto""stripIfInteger" », "auto")。
  12. 注:SetNumberFormatDigitOptions 所需的所有字段现已从 options 读取。后续算法用于解释选项并可能抛出异常。
  13. 如果 roundingIncrement 不为 1,则将 mxfdDefault 设为 mnfdDefault
  14. intlObj.[[RoundingIncrement]] 设为 roundingIncrement
  15. intlObj.[[RoundingMode]] 设为 roundingMode
  16. intlObj.[[TrailingZeroDisplay]] 设为 trailingZeroDisplay
  17. 如果 mnsdundefinedmxsdundefined,则令 hasSdfalse。 否则令 hasSdtrue
  18. 如果 mnfdundefinedmxfdundefined,则令 hasFdfalse。 否则令 hasFdtrue
  19. needSdtrue
  20. needFdtrue
  21. 如果 roundingPriority"auto",则
    1. needSd 设为 hasSd
    2. 如果 needSdtrue,或 hasFdfalsenotation"compact",则
      1. needFd 设为 false
  22. 如果 needSdtrue,则
    1. 如果 hasSdtrue,则
      1. intlObj.[[MinimumSignificantDigits]] 设为 ? DefaultNumberOption(mnsd, 1,21,1)。
      2. intlObj.[[MaximumSignificantDigits]] 设为 ? DefaultNumberOption(mxsdintlObj.[[MinimumSignificantDigits]],21,21)。
    2. 否则,
      1. intlObj.[[MinimumSignificantDigits]] 设为 1。
      2. intlObj.[[MaximumSignificantDigits]] 设为 21。
  23. 如果 needFdtrue,则
    1. 如果 hasFdtrue,则
      1. mnfd 设为 ? DefaultNumberOption(mnfd, 0,100,undefined)。
      2. mxfd 设为 ? DefaultNumberOption(mxfd, 0,100,undefined)。
      3. 如果 mnfdundefined,则将 mnfd 设为 min(mnfdDefaultmxfd)。
      4. 否则如果 mxfdundefined,则将 mxfd 设为 max(mxfdDefaultmnfd)。
      5. 否则如果 mnfd 大于 mxfd,则抛出 RangeError 异常。
      6. intlObj.[[MinimumFractionDigits]] 设为 mnfd
      7. intlObj.[[MaximumFractionDigits]] 设为 mxfd
    2. 否则,
      1. intlObj.[[MinimumFractionDigits]] 设为 mnfdDefault
      2. intlObj.[[MaximumFractionDigits]] 设为 mxfdDefault
  24. 如果 needSdfalseneedFdfalse,则
    1. intlObj.[[MinimumFractionDigits]] 设为 0。
    2. intlObj.[[MaximumFractionDigits]] 设为 0。
    3. intlObj.[[MinimumSignificantDigits]] 设为 1。
    4. intlObj.[[MaximumSignificantDigits]] 设为 2。
    5. intlObj.[[RoundingType]] 设为 more-precision
    6. intlObj.[[ComputedRoundingPriority]] 设为 "morePrecision"
  25. 否则如果 roundingPriority"morePrecision",则
    1. intlObj.[[RoundingType]] 设为 more-precision
    2. intlObj.[[ComputedRoundingPriority]] 设为 "morePrecision"
  26. 否则如果 roundingPriority"lessPrecision",则
    1. intlObj.[[RoundingType]] 设为 less-precision
    2. intlObj.[[ComputedRoundingPriority]] 设为 "lessPrecision"
  27. 否则如果 hasSdtrue,则
    1. intlObj.[[RoundingType]] 设为 significant-digits
    2. intlObj.[[ComputedRoundingPriority]] 设为 "auto"
  28. 否则,
    1. intlObj.[[RoundingType]] 设为 fraction-digits
    2. intlObj.[[ComputedRoundingPriority]] 设为 "auto"
  29. 如果 roundingIncrement 不为 1,则
    1. 如果 intlObj.[[RoundingType]] 不为 fraction-digits,则抛出 TypeError 异常。
    2. 如果 intlObj.[[MaximumFractionDigits]] 不为 intlObj.[[MinimumFractionDigits]],则抛出 RangeError 异常。
  30. 返回 unused

16.1.3 SetNumberFormatUnitOptions ( intlObjoptions )

抽象操作 SetNumberFormatUnitOptions 接受参数 intlObj(一个 Intl.NumberFormat)与 options(一个对象),并返回一个正常完成,包含unused或一个抛出完成。该操作将与单位相关的用户指定选项解析到 intlObj 上。调用时执行以下步骤:

  1. style 为 ? GetOption(options"style"string,« "decimal""percent""currency""unit" », "decimal")。
  2. intlObj.[[Style]] 设为 style
  3. currency 为 ? GetOption(options"currency"stringemptyundefined)。
  4. 如果 currencyundefined,则
    1. 如果 style"currency",则抛出 TypeError 异常。
  5. 否则,
    1. 如果 IsWellFormedCurrencyCode(currency) 为 false,则抛出 RangeError 异常。
  6. currencyDisplay 为 ? GetOption(options"currencyDisplay"string,« "code""symbol""narrowSymbol""name" », "symbol")。
  7. currencySign 为 ? GetOption(options"currencySign"string,« "standard""accounting" », "standard")。
  8. unit 为 ? GetOption(options"unit"stringemptyundefined)。
  9. 如果 unitundefined,则
    1. 如果 style"unit",则抛出 TypeError 异常。
  10. 否则,
    1. 如果 IsWellFormedUnitIdentifier(unit) 为 false,则抛出 RangeError 异常。
  11. unitDisplay 为 ? GetOption(options"unitDisplay"string,« "short""narrow""long" »,"short")。
  12. 如果 style"currency",则
    1. intlObj.[[Currency]] 设为 ASCII-uppercase(currency)。
    2. intlObj.[[CurrencyDisplay]] 设为 currencyDisplay
    3. intlObj.[[CurrencySign]] 设为 currencySign
  13. 如果 style"unit",则
    1. intlObj.[[Unit]] 设为 unit
    2. intlObj.[[UnitDisplay]] 设为 unitDisplay
  14. 返回 unused

16.2 Intl.NumberFormat 构造函数的属性

Intl.NumberFormat 构造函数

16.2.1 Intl.NumberFormat.prototype

Intl.NumberFormat.prototype 的值为 %Intl.NumberFormat.prototype%

此属性具有属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

16.2.2 Intl.NumberFormat.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行如下步骤:

  1. availableLocales%Intl.NumberFormat%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocales, requestedLocales, options)。

16.2.3 内部槽

[[AvailableLocales]] 内部槽的值为 实现自定义,并受 9.1 约束。

[[RelevantExtensionKeys]] 内部槽的值为 « "nu" »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « { [[Key]]: "nu", [[Property]]: "numberingSystem" } »。

注 1
Unicode Technical Standard #35 Part 1 Core, Section 3.6.1 Key and Type Definitions 描述了三个与数字格式相关的语言环境扩展键:"cu" 表示货币,"cf" 表示货币格式样式,"nu" 表示数字系统。但 Intl.NumberFormat 要求货币格式的货币通过选项对象中的 currency 属性指定,货币格式样式通过选项对象中的 currencySign 属性指定。

[[LocaleData]] 内部槽的值为 实现自定义,并受 9.1 及以下约束:

  • 任何语言环境字段 "nu" 的值所对应的 List,不得包含 "native""traditio""finance"
  • [[LocaleData]].[[<locale>]] 必须对所有 locale[[patterns]] 字段。该字段必须为 Record,且包含四种数字格式样式对应的字段名:"decimal""percent""currency""unit"
  • 上述 "currency""unit" 字段必须是 Records,且至少有一个字段 "fallback""currency" 还可以有额外字段,其键为 6.3 规定的货币代码。 "currency" 的每个字段必须是 Record,字段名对应所有可用的 currencyDisplay:"code""symbol""narrowSymbol""name"。 其中每个字段都必须包含一个 Record,字段名为可用的 currencySign:"standard""accounting""unit" 字段(在 [[LocaleData]].[[<locale>]] 中)除了必需的 "fallback" 字段外,还可以有其他字段,键为 6.6 规定的测量单位标识符。 "unit" 的每个字段必须是 Record,字段名为所有可用的 unitDisplay:"narrow""short""long"
  • 所有目前描述的 patterns 树的叶字段("decimal""percent""currency" 的曾孙、"unit" 的孙字段)都必须是 Records,键为 "positivePattern""zeroPattern""negativePattern"
  • 上述字段的值(与符号相关的 pattern 字段)必须为字符串,且必须包含 子串 "{number}""positivePattern" 必须包含 子串 "{plusSign}" 且不能包含 "{minusSign}""negativePattern" 必须包含 子串 "{minusSign}" 且不能包含 "{plusSign}""zeroPattern" 不得包含 "{plusSign}""{minusSign}"。 此外,"percent" 字段中的值还必须包含 子串 "{percentSign}""currency" 字段中的值还必须包含以下子串之一或多个:"{currencyCode}""{currencyPrefix}""{currencySuffix}""unit" 字段中的值还必须包含以下子串之一或多个:"{unitPrefix}""{unitSuffix}"。 这些 pattern 字符串在按 ECMA-2626.1.4 规定的 UTF-16 编码点顺序解释时,不得包含 Unicode 标准中 General Category "Number, decimal digit" 的编码点。
  • [[LocaleData]].[[<locale>]] 对所有 locale 还必须有 [[notationSubPatterns]] 字段。其值必须是 Record,且包含两个字段:[[scientific]][[compact]][[scientific]] 字段必须为字符串,包含 "{number}""{scientificSeparator}""{scientificExponent}" 子串。 [[compact]] 字段必须是 Record,包含 "short""long" 两字段。每个字段都必须是 Record,其键为实现支持的所有 compact notation 离散数量级的 整数。每个字段的值必须为字符串,可以包含 子串 "{number}"。所有 "short" 的后代字符串都必须包含 子串 "{compactSymbol}",所有 "long" 的后代字符串都必须包含 子串 "{compactName}"
注 2
建议实现使用 Common Locale Data Repository(CLDR,https://cldr.unicode.org/)提供的语言环境数据。

16.3 Intl.NumberFormat 原型对象的属性

Intl.NumberFormat 原型对象

  • %Intl.NumberFormat.prototype%
  • 是一个普通对象
  • 不是 Intl.NumberFormat 实例,且不具有 [[InitializedNumberFormat]] 内部槽或 Intl.NumberFormat 实例对象的其他内部槽。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%

16.3.1 Intl.NumberFormat.prototype.constructor

Intl.NumberFormat.prototype.constructor 的初始值为 %Intl.NumberFormat%

16.3.2 Intl.NumberFormat.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境与选项。

  1. nfthis 值。
  2. 如果实现支持 构造函数的规范可选模式 4.3 注 1,则
    1. nf 设为 ? UnwrapNumberFormat(nf)。
  3. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  4. optionsOrdinaryObjectCreate(%Object.prototype%)。
  5. 按表序,对 表 26 的每一行(除表头行)执行:
    1. p 为当前行 Property 列的值。
    2. vnf 的内部槽中名称为当前行 Internal Slot 列的槽的值。
    3. vundefined,则
      1. 若当前行有 Conversion 列值,则
        1. 断言: 当前行 Conversion 列值为 number
        2. v 设为 𝔽(v)。
      2. 执行 ! CreateDataPropertyOrThrow(options, p, v)。
  6. 返回 options
表 26:NumberFormat 实例的已解析选项
内部槽 属性 转换
[[Locale]] "locale"
[[NumberingSystem]] "numberingSystem"
[[Style]] "style"
[[Currency]] "currency"
[[CurrencyDisplay]] "currencyDisplay"
[[CurrencySign]] "currencySign"
[[Unit]] "unit"
[[UnitDisplay]] "unitDisplay"
[[MinimumIntegerDigits]] "minimumIntegerDigits" number
[[MinimumFractionDigits]] "minimumFractionDigits" number
[[MaximumFractionDigits]] "maximumFractionDigits" number
[[MinimumSignificantDigits]] "minimumSignificantDigits" number
[[MaximumSignificantDigits]] "maximumSignificantDigits" number
[[UseGrouping]] "useGrouping"
[[Notation]] "notation"
[[CompactDisplay]] "compactDisplay"
[[SignDisplay]] "signDisplay"
[[RoundingIncrement]] "roundingIncrement" number
[[RoundingMode]] "roundingMode"
[[ComputedRoundingPriority]] "roundingPriority"
[[TrailingZeroDisplay]] "trailingZeroDisplay"

16.3.3 get Intl.NumberFormat.prototype.format

Intl.NumberFormat.prototype.format 是一个访问器属性,其 setter 为 undefined。getter 执行如下步骤:

  1. nfthis 值。
  2. 如果实现支持 构造函数的规范可选模式 4.3 注 1,则
    1. nf 设为 ? UnwrapNumberFormat(nf)。
  3. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  4. 如果 nf.[[BoundFormat]]undefined,则
    1. F 为新的内建 函数对象,定义见 Number Format Functions(16.5.2)。
    2. F.[[NumberFormat]] 设为 nf
    3. nf.[[BoundFormat]] 设为 F
  5. 返回 nf.[[BoundFormat]]
返回的函数与 nf 绑定,因此可以直接传递给 Array.prototype.map 或其它函数。 这是一个历史遗留惯例,新特性已不再遵循,但为兼容旧程序而保留。

16.3.4 Intl.NumberFormat.prototype.formatRange ( start, end )

当以参数 startend 调用 formatRange 方法时,执行如下步骤:

  1. nfthis 值。
  2. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  3. 如果 startundefinedendundefined,则抛出 TypeError 异常。
  4. x 为 ? ToIntlMathematicalValue(start)。
  5. y 为 ? ToIntlMathematicalValue(end)。
  6. 返回 ? FormatNumericRange(nf, x, y)。

16.3.5 Intl.NumberFormat.prototype.formatRangeToParts ( start, end )

当以参数 startend 调用 formatRangeToParts 方法时,执行如下步骤:

  1. nfthis 值。
  2. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  3. 如果 startundefinedendundefined,则抛出 TypeError 异常。
  4. x 为 ? ToIntlMathematicalValue(start)。
  5. y 为 ? ToIntlMathematicalValue(end)。
  6. 返回 ? FormatNumericRangeToParts(nf, x, y)。

16.3.6 Intl.NumberFormat.prototype.formatToParts ( value )

当以可选参数 value 调用 formatToParts 方法时,执行如下步骤:

  1. nfthis 值。
  2. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  3. x 为 ? ToIntlMathematicalValue(value)。
  4. 返回 FormatNumericToParts(nf, x)。

16.3.7 Intl.NumberFormat.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.NumberFormat"

此属性具有属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

16.4 Intl.NumberFormat 实例的属性

Intl.NumberFormat 实例是普通对象,它继承自 %Intl.NumberFormat.prototype% 的属性。

Intl.NumberFormat 实例具有 [[InitializedNumberFormat]] 内部槽。

Intl.NumberFormat 实例还具有一些由 Intl.NumberFormat 构造函数 计算出的内部槽:

  • [[Locale]] 是字符串,其值为该语言环境的 language tag,用于格式化时本地化。
  • [[LocaleData]] 是一个 Record,表示实现可用于格式化的数据。它是 %Intl.NumberFormat%.[[LocaleData]] 中,与 [[Locale]] 的值或其前缀相关的条目的值。
  • [[NumberingSystem]] 是字符串,表示用于格式化的 Unicode 数字系统标识符
  • [[Style]] 是字符串值之一:"decimal""currency""percent""unit", 用于标识所度量的数量类型。
  • [[Currency]] 是字符串,其值为货币代码,指定如 "currency" 单位类型格式化时所用的货币。仅当 [[Style]] 的值为 "currency" 时使用。
  • [[CurrencyDisplay]] 是字符串值之一:"code""symbol""narrowSymbol""name",指定以 ISO 4217 货币代码、本地化货币符号或本地化货币名称显示货币。仅当 [[Style]] 的值为 "currency" 时使用。
  • [[CurrencySign]] 是字符串值之一:"standard""accounting",指定是否以会计格式显示负数,通常使用括号。仅当 [[Style]] 的值为 "currency"[[SignDisplay]]"never" 时使用。
  • [[Unit]] 是一个 核心单位标识符。仅当 [[Style]] 的值为 "unit" 时使用。
  • [[UnitDisplay]] 是字符串值之一:"short""narrow""long",指定当以 "unit" 样式格式化时以符号、窄符号或本地化长名称显示单位。仅当 [[Style]] 的值为 "unit" 时使用。
  • [[MinimumIntegerDigits]] 是非负 整数,表示要使用的最小整数位数。数字必要时会用前导零填充。
  • [[MinimumFractionDigits]][[MaximumFractionDigits]] 是非负 整数,表示要使用的最小和最大小数位数。必要时数字会四舍五入或用零补齐。这些属性仅当 [[RoundingType]]fraction-digitsmore-precisionless-precision 时使用。
  • [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 是正 整数,表示要显示的最小和最大有效数字。如果存在,格式化器将使用足够的小数位来显示指定数量的有效数字。这些属性仅当 [[RoundingType]]significant-digitsmore-precisionless-precision 时使用。
  • [[UseGrouping]] 是布尔值或字符串,表示何时使用分组分隔符。分组分隔符的位置以及是否显示分组分隔符为实现自定义"always" 表示尽可能显示分组分隔符;"min2" 表示当分组至少有 2 位时显示;"auto" 表示依照语言环境偏好显示分组分隔符。false 表示禁用分组分隔符。
  • [[RoundingType]]fraction-digitssignificant-digitsmore-precisionless-precision,表示使用哪种舍入策略。如果为 fraction-digits,则按照 [[MinimumFractionDigits]][[MaximumFractionDigits]] 舍入;若为 significant-digits,则按照 [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 舍入;若为 more-precisionless-precision,则上述四项都会用,具体规则见相关说明。[[RoundingType]] 来源于 "roundingPriority" 选项。
  • [[ComputedRoundingPriority]] 是字符串值之一:"auto""morePrecision""lessPrecision"。仅在 16.3.2 用于将 [[RoundingType]] 转换回有效的 "roundingPriority" 选项。
  • [[Notation]] 是字符串值之一:"standard""scientific""engineering""compact",指定格式化数字应否缩放、不缩放、以科学计数法缩放到个位、以科学计数法缩放到千位或用语言环境依赖的紧缩十进制后缀缩放到相应数量级。
  • [[CompactDisplay]] 是字符串值之一:"short""long",指定当以 "compact" 记号格式化时使用短表述(如 "5K")还是长表述(如 "5 thousand")。仅当 [[Notation]] 的值为 "compact" 时使用。
  • [[SignDisplay]] 是字符串值之一:"auto""always""never""exceptZero""negative",指定何时显示符号(除了 "auto" 外,分别表示总是、从不、仅非零或仅非零负数显示)。在科学记数法下,该槽影响尾数的符号显示,不影响指数。
  • [[RoundingIncrement]] 是一个 整数,可整除 10、100、1000 或 10000,表示舍入时采用的增量。例如,当 [[MaximumFractionDigits]] 为 2 且 [[RoundingIncrement]] 为 5 时,数字将按最接近的 0.05 四舍五入(即 "nickel rounding")。
  • [[RoundingMode]] 是一种 舍入模式,为 表 27 Identifier 列的字符串值之一。
  • [[TrailingZeroDisplay]] 是字符串值之一:"auto""stripIfInteger",表示当格式化结果为整数(即无非零小数位)时是否去除尾随零。
表 27:Intl.NumberFormat 的舍入模式
标识符 描述 举例:舍入到 0 个小数位
-1.5 0.4 0.5 0.6 1.5
"ceil" 趋向正无穷 ⬆️ [-1] ⬆️ [1] ⬆️ [1] ⬆️ [1] ⬆️ [2]
"floor" 趋向负无穷 ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬇️ [0] ⬇️ [1]
"expand" 远离零 ⬇️ [-2] ⬆️ [1] ⬆️ [1] ⬆️ [1] ⬆️ [2]
"trunc" 趋向零 ⬆️ [-1] ⬇️ [0] ⬇️ [0] ⬇️ [0] ⬇️ [1]
"halfCeil" 五舍六入趋向正无穷 ⬆️ [-1] ⬇️ [0] ⬆️ [1] ⬆️ [1] ⬆️ [2]
"halfFloor" 五舍六入趋向负无穷 ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬇️ [1]
"halfExpand" 五舍六入远离零 ⬇️ [-2] ⬇️ [0] ⬆️ [1] ⬆️ [1] ⬆️ [2]
"halfTrunc" 五舍六入趋向零 ⬆️ [-1] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬇️ [1]
"halfEven" 五舍六入趋向偶数舍入增量倍数 ⬇️ [-2] ⬇️ [0] ⬇️ [0] ⬆️ [1] ⬆️ [2]
举例用于说明各选项的独特行为。⬆️ 表示“趋向正无穷”;⬇️ 表示“趋向负无穷”。

最后,Intl.NumberFormat 实例有一个 [[BoundFormat]] 内部槽,用于缓存 format 访问器返回的函数(见 16.3.3)。

16.5 NumberFormat 对象的抽象操作

16.5.1 CurrencyDigits ( currency )

实现自定义 抽象操作 CurrencyDigits 接收参数 currency(字符串),返回一个非负整数。调用时执行以下步骤:

  1. 断言IsWellFormedCurrencyCode(currency) 为 true
  2. 返回一个非负整数,表示格式化该货币时使用的小数位数。如果没有相关信息,则返回 2。

16.5.2 Number 格式化函数

Number 格式化函数是一个匿名内建函数,具有 [[NumberFormat]] 内部槽。

当 Number 格式化函数 F 以可选参数 value 被调用时,执行以下步骤:

  1. nfF.[[NumberFormat]]
  2. 断言nf 是对象,并且 nf 具有 [[InitializedNumberFormat]] 内部槽。
  3. 如果 value 未提供,则令 valueundefined
  4. x 为 ? ToIntlMathematicalValue(value)。
  5. 返回 FormatNumeric(nf, x)。

Number 格式化函数的 "length" 属性为 1𝔽

16.5.3 FormatNumericToString ( intlObject, x )

抽象操作 FormatNumericToString 接收参数 intlObject(对象)和 x(一个数学值negative-zero),返回一个Record, 其字段为 [[RoundedNumber]]数学值negative-zero)和 [[FormattedString]](字符串)。它根据 intlObject 的内部槽对 x 进行舍入。[[RoundedNumber]] 字段为舍入后的结果值,[[FormattedString]] 字段为根据 intlObject 的内部槽格式化后的字符串表示。调用时执行以下步骤:

  1. 断言intlObject 具有 [[RoundingMode]][[RoundingType]][[MinimumSignificantDigits]][[MaximumSignificantDigits]][[MinimumIntegerDigits]][[MinimumFractionDigits]][[MaximumFractionDigits]][[RoundingIncrement]][[TrailingZeroDisplay]] 内部槽。
  2. 如果 xnegative-zero,则
    1. signnegative
    2. x 设为 0。
  3. 否则,
    1. 断言x 是一个数学值
    2. 如果 x < 0,则令 signnegative;否则令 signpositive
    3. 如果 signnegative,则
      1. x 设为 -x
  4. unsignedRoundingModeGetUnsignedRoundingMode(intlObject.[[RoundingMode]], sign)。
  5. 如果 intlObject.[[RoundingType]]significant-digits,则
    1. resultToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode)。
  6. 否则如果 intlObject.[[RoundingType]]fraction-digits,则
    1. resultToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode)。
  7. 否则,
    1. sResultToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode)。
    2. fResultToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode)。
    3. 如果 fResult.[[RoundingMagnitude]] < sResult.[[RoundingMagnitude]],令 fixedIsMorePrecisetrue;否则令 fixedIsMorePrecisefalse
    4. 如果 intlObject.[[RoundingType]]more-precisionfixedIsMorePrecisetrue,则
      1. resultfResult
    5. 否则如果 intlObject.[[RoundingType]]less-precisionfixedIsMorePrecisefalse,则
      1. resultfResult
    6. 否则,
      1. resultsResult
  8. x 设为 result.[[RoundedNumber]]
  9. stringresult.[[FormattedString]]
  10. 如果 intlObject.[[TrailingZeroDisplay]]"stripIfInteger"x 1 = 0,则
    1. iStringIndexOf(string, ".", 0)。
    2. 如果 inot-found,则将 string 设为 string 从 0 到 i子串
  11. intresult.[[IntegerDigitsCount]]
  12. minIntegerintlObject.[[MinimumIntegerDigits]]
  13. 如果 int < minInteger,则
    1. forwardZeros 为字符串,由 minInteger - int 个 0x0030(数字零)组成。
    2. string 设为 字符串连接(forwardZeros, string)。
  14. 如果 signnegative,则
    1. 如果 x 为 0,则将 x 设为 negative-zero。否则,将 x 设为 -x
  15. 返回 Record { [[RoundedNumber]]: x, [[FormattedString]]: string }。

16.5.4 PartitionNumberPattern ( numberFormat, x )

抽象操作 PartitionNumberPattern 接收参数 numberFormat(一个初始化为 NumberFormat 的对象)和 x(一个Intl 数学值),返回一个List, 其中包含字段 [[Type]](字符串)和 [[Value]](字符串)的Records。它根据当前语言环境和 numberFormat 的格式化选项,创建表示 数学值 x 的各部分。调用时执行以下步骤:

  1. exponent 为 0。
  2. 如果 xnot-a-number,则
    1. n 为一个ILD 字符串值,用于表示 NaN
  3. 否则如果 xpositive-infinity,则
    1. n 为一个ILD 字符串值,用于表示正无穷。
  4. 否则如果 xnegative-infinity,则
    1. n 为一个ILD 字符串值,用于表示负无穷。
  5. 否则,
    1. 如果 xnegative-zero,则
      1. 断言x 是一个数学值
      2. 如果 numberFormat.[[Style]]"percent",将 x 设为 100 × x
      3. exponent 设为 ComputeExponent(numberFormat, x)。
      4. x 设为 x × 10-exponent
    2. formatNumberResultFormatNumericToString(numberFormat, x)。
    3. nformatNumberResult.[[FormattedString]]
    4. x 设为 formatNumberResult.[[RoundedNumber]]
  6. patternGetNumberFormatPattern(numberFormat, x)。
  7. result 为一个新的空List
  8. patternPartsPartitionPattern(pattern)。
  9. patternParts 中的每个 Record { [[Type]], [[Value]] } patternPart,执行:
    1. ppatternPart.[[Type]]
    2. 如果 p"literal",则
      1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } 追加到 result
    3. 否则如果 p"number",则
      1. notationSubPartsPartitionNotationSubPattern(numberFormat, x, n, exponent)。
      2. result 设为 列表连接(result, notationSubParts)。
    4. 否则如果 p"plusSign",则
      1. plusSignSymbolILND 表示加号的字符串。
      2. Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } 追加到 result
    5. 否则如果 p"minusSign",则
      1. minusSignSymbolILND 表示减号的字符串。
      2. Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } 追加到 result
    6. 否则如果 p"percentSign"numberFormat.[[Style]]"percent",则
      1. percentSignSymbolILND 表示百分号的字符串。
      2. Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } 追加到 result
    7. 否则如果 p"unitPrefix"numberFormat.[[Style]]"unit",则
      1. unitnumberFormat.[[Unit]]
      2. unitDisplaynumberFormat.[[UnitDisplay]]
      3. muILD 表示 unitunitDisplay 形式下位于 x 前的字符串,该字符串可能因不同语言的复数形式而依赖 x
      4. Record { [[Type]]: "unit", [[Value]]: mu } 追加到 result
    8. 否则如果 p"unitSuffix"numberFormat.[[Style]]"unit",则
      1. unitnumberFormat.[[Unit]]
      2. unitDisplaynumberFormat.[[UnitDisplay]]
      3. muILD 表示 unitunitDisplay 形式下位于 x 后的字符串,该字符串可能因不同语言的复数形式而依赖 x
      4. Record { [[Type]]: "unit", [[Value]]: mu } 追加到 result
    9. 否则如果 p"currencyCode"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. cdcurrency
      3. Record { [[Type]]: "currency", [[Value]]: cd } 追加到 result
    10. 否则如果 p"currencyPrefix"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. currencyDisplaynumberFormat.[[CurrencyDisplay]]
      3. cdILD 表示 currencycurrencyDisplay 形式下位于 x 前的字符串,该字符串可能因不同语言的复数形式而依赖 x
      4. Record { [[Type]]: "currency", [[Value]]: cd } 追加到 result
    11. 否则如果 p"currencySuffix"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. currencyDisplaynumberFormat.[[CurrencyDisplay]]
      3. cdILD 表示 currencycurrencyDisplay 形式下位于 x 后的字符串,该字符串可能因不同语言的复数形式而依赖 x。如果实现没有这样的表示,则使用 currency 本身。
      4. Record { [[Type]]: "currency", [[Value]]: cd } 追加到 result
    12. 否则,
      1. unknownILND 基于 xp 的字符串。
      2. Record { [[Type]]: "unknown", [[Value]]: unknown } 追加到 result
  10. 返回 result

16.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent )

抽象操作 PartitionNotationSubPattern 接收参数 numberFormat(一个 Intl.NumberFormat)、x(一个Intl 数学值)、n(字符串)、exponent(一个整数),返回一个List, 元素为包含字段 [[Type]](字符串)和 [[Value]](字符串)的Recordsx 为应用舍入后的Intl 数学值n为中间格式化字符串。 此操作根据当前语言环境和 numberFormat 的格式化选项,为数字和记号创建相应分段。调用时执行如下步骤:

  1. result 为一个新的空List
  2. 如果 xnot-a-number,则
    1. Record { [[Type]]: "nan", [[Value]]: n } 追加到 result
  3. 否则如果 xpositive-infinitynegative-infinity,则
    1. Record { [[Type]]: "infinity", [[Value]]: n } 追加到 result
  4. 否则,
    1. notationSubPatternGetNotationSubPattern(numberFormat, exponent)。
    2. patternPartsPartitionPattern(notationSubPattern)。
    3. patternParts 的每个 Record { [[Type]], [[Value]] } patternPart,执行:
      1. ppatternPart.[[Type]]
      2. 如果 p"literal",则
        1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } 追加到 result
      3. 否则如果 p"number",则
        1. 如果 numberFormat.[[NumberingSystem]] 匹配下表(表 28)中 Numbering System 列的任一值,则
          1. digits 为一个 List, 元素为匹配行 Digits 列所指定的码点。
          2. 断言digits 长度为 10。
          3. transliterated 为空字符串。
          4. lenn 的长度。
          5. position 为 0。
          6. 重复,当 position < len 时,
            1. cn 中索引为 position 处的码元。
            2. 如果 0x0030 ≤ c ≤ 0x0039,则
              1. 注:c 为 ASCII 数字。
              2. ic - 0x0030。
              3. c 设为 CodePointsToStringdigits[i] »)。
            3. transliterated 设为 字符串连接(transliterated, c)。
            4. position 设为 position + 1。
          7. n 设为 transliterated
        2. 否则,
          1. 使用实现自定义算法将 n 映射为指定数字系统下的适当表示。
        3. decimalSepIndexStringIndexOf(n, ".", 0)。
        4. 如果 decimalSepIndexnot-founddecimalSepIndex > 0,则
          1. integer子串(n, 0, decimalSepIndex)。
          2. fraction子串(n, decimalSepIndex + 1)。
        5. 否则,
          1. integern
          2. fractionundefined
        6. 如果 numberFormat.[[UseGrouping]]false,则
          1. Record { [[Type]]: "integer", [[Value]]: integer } 追加到 result
        7. 否则,
          1. groupSepSymbolILND 表示分组分隔符的字符串。
          2. groups 为一个 List,元素为从左到右的子串,由 ILND 所定义的位置决定,具体取决于 numberFormat.[[UseGrouping]] 的值。
          3. 断言groups 元素个数大于 0。
          4. 重复,当 groups 非空时,
            1. 移除 groups 的第一个元素,令 integerGroup 为该值。
            2. Record { [[Type]]: "integer", [[Value]]: integerGroup } 追加到 result
            3. 如果 groups 非空,则
              1. Record { [[Type]]: "group", [[Value]]: groupSepSymbol } 追加到 result
        8. 如果 fractionundefined,则
          1. decimalSepSymbolILND 表示小数点的字符串。
          2. Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } 追加到 result
          3. Record { [[Type]]: "fraction", [[Value]]: fraction } 追加到 result
      4. 否则如果 p"compactSymbol",则
        1. compactSymbolILD 字符串,表示 exponent 的短格式,可能会根据 x 的不同复数形式而变化。实现必须能够提供该字符串,否则模式不会有 "{compactSymbol}" 占位。
        2. Record { [[Type]]: "compact", [[Value]]: compactSymbol } 追加到 result
      5. 否则如果 p"compactName",则
        1. compactNameILD 字符串,表示 exponent 的长格式,可能会根据 x 的不同复数形式而变化。实现必须能够提供该字符串,否则模式不会有 "{compactName}" 占位。
        2. Record { [[Type]]: "compact", [[Value]]: compactName } 追加到 result
      6. 否则如果 p"scientificSeparator",则
        1. scientificSeparatorILND 表示指数分隔符的字符串。
        2. Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } 追加到 result
      7. 否则如果 p"scientificExponent",则
        1. 如果 exponent < 0,则
          1. minusSignSymbolILND 表示减号的字符串。
          2. Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } 追加到 result
          3. exponent 为 -exponent
        2. exponentResultToRawFixed(exponent, 0, 0, 1, undefined)。
        3. Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } 追加到 result
      8. 否则,
        1. unknownILND 基于 xp 的字符串。
        2. Record { [[Type]]: "unknown", [[Value]]: unknown } 追加到 result
  5. 返回 result
表 28:带有简单数字映射的数字系统
数字系统 数字码点
adlm U+1E950 至 U+1E959
ahom U+11730 至 U+11739
arab U+0660 至 U+0669
arabext U+06F0 至 U+06F9
bali U+1B50 至 U+1B59
beng U+09E6 至 U+09EF
bhks U+11C50 至 U+11C59
brah U+11066 至 U+1106F
cakm U+11136 至 U+1113F
cham U+AA50 至 U+AA59
deva U+0966 至 U+096F
diak U+11950 至 U+11959
fullwide U+FF10 至 U+FF19
gara U+10D40 至 U+10D49
gong U+11DA0 至 U+11DA9
gonm U+11D50 至 U+11D59
gujr U+0AE6 至 U+0AEF
gukh U+16130 至 U+16139
guru U+0A66 至 U+0A6F
hanidec U+3007, U+4E00, U+4E8C, U+4E09, U+56DB, U+4E95, U+516D, U+4E03, U+516B, U+4E5D
hmng U+16B50 至 U+16B59
hmnp U+1E140 至 U+1E149
java U+A9D0 至 U+A9D9
kali U+A900 至 U+A909
kawi U+11F50 至 U+11F59
khmr U+17E0 至 U+17E9
knda U+0CE6 至 U+0CEF
krai U+16D70 至 U+16D79
lana U+1A80 至 U+1A89
lanatham U+1A90 至 U+1A99
laoo U+0ED0 至 U+0ED9
latn U+0030 至 U+0039
lepc U+1C40 至 U+1C49
limb U+1946 至 U+194F
mathbold U+1D7CE 至 U+1D7D7
mathdbl U+1D7D8 至 U+1D7E1
mathmono U+1D7F6 至 U+1D7FF
mathsanb U+1D7EC 至 U+1D7F5
mathsans U+1D7E2 至 U+1D7EB
mlym U+0D66 至 U+0D6F
modi U+11650 至 U+11659
mong U+1810 至 U+1819
mroo U+16A60 至 U+16A69
mtei U+ABF0 至 U+ABF9
mymr U+1040 至 U+1049
mymrepka U+116DA 至 U+116E3
mymrpao U+116D0 至 U+116D9
mymrshan U+1090 至 U+1099
mymrtlng U+A9F0 至 U+A9F9
nagm U+1E4F0 至 U+1E4F9
newa U+11450 至 U+11459
nkoo U+07C0 至 U+07C9
olck U+1C50 至 U+1C59
onao U+1E5F1 至 U+1E5FA
orya U+0B66 至 U+0B6F
osma U+104A0 至 U+104A9
outlined U+1CCF0 至 U+1CCF9
rohg U+10D30 至 U+10D39
saur U+A8D0 至 U+A8D9
segment U+1FBF0 至 U+1FBF9
shrd U+111D0 至 U+111D9
sind U+112F0 至 U+112F9
sinh U+0DE6 至 U+0DEF
sora U+110F0 至 U+110F9
sund U+1BB0 至 U+1BB9
sunu U+11BF0 至 U+11BF9
takr U+116C0 至 U+116C9
talu U+19D0 至 U+19D9
tamldec U+0BE6 至 U+0BEF
telu U+0C66 至 U+0C6F
thai U+0E50 至 U+0E59
tibt U+0F20 至 U+0F29
tirh U+114D0 至 U+114D9
tnsa U+16AC0 至 U+16AC9
vaii U+A620 至 U+A629
wara U+118E0 至 U+118E9
wcho U+1E2F0 至 U+1E2F9
注 1
相关计算依赖于 ILDILND 字符串值,以及取决于 numberFormat 当前语言环境或语言环境和数字系统的数字字符串分段位置。上述 ILDILND 字符串值(货币名称除外)不得包含 Unicode 标准 General Category "Number, decimal digit" 的编码点。
注 2
建议实现使用 Common Locale Data Repository(CLDR,https://cldr.unicode.org/)中提供的语言环境数据。

16.5.6 FormatNumeric ( numberFormat, x )

抽象操作 FormatNumeric 接收参数 numberFormat(一个 Intl.NumberFormat)和 x(一个Intl 数学值),返回一个字符串。调用时执行以下步骤:

  1. partsPartitionNumberPattern(numberFormat, x)。
  2. result 为空字符串。
  3. parts 中的每个 Record { [[Type]], [[Value]] } part,执行:
    1. result 设为 字符串连接(result, part.[[Value]])。
  4. 返回 result

16.5.7 FormatNumericToParts ( numberFormat, x )

抽象操作 FormatNumericToParts 接收参数 numberFormat(一个 Intl.NumberFormat)和 x(一个Intl 数学值),返回一个数组。调用时执行以下步骤:

  1. partsPartitionNumberPattern(numberFormat, x)。
  2. result 为 !ArrayCreate(0)。
  3. n 为 0。
  4. parts 中每个 Record { [[Type]], [[Value]] } part,执行:
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 !CreateDataPropertyOrThrow(O, "type", part.[[Type]])。
    3. 执行 !CreateDataPropertyOrThrow(O, "value", part.[[Value]])。
    4. 执行 !CreateDataPropertyOrThrow(result, !ToString(𝔽(n)), O)。
    5. n 加 1。
  5. 返回 result

16.5.8 ToRawPrecision ( x, minPrecision, maxPrecision, unsignedRoundingMode )

抽象操作 ToRawPrecision 接收参数 x(一个非负数学值)、minPrecision(一个整数,取值范围为 1 到 21)、maxPrecision(一个整数,取值范围为 1 到 21)、unsignedRoundingMode(一个取自表 29 Unsigned Rounding Mode 列的规范类型或 undefined),返回一个Record,字段包括 [[FormattedString]](字符串)、[[RoundedNumber]](数学值)、[[IntegerDigitsCount]](整数)、[[RoundingMagnitude]](整数)。

此操作涉及求解下列方程,输入为整数时返回有效的数学值

ToRawPrecisionFn(n, e, p) = n × 10ep+1
其中 10p–1n < 10p

调用时执行以下步骤:

  1. pmaxPrecision
  2. 如果 x = 0,则
    1. m 为包含 p 个 0x0030(数字零)的字符串。
    2. e 为 0。
    3. xFinal 为 0。
  3. 否则,
    1. n1e1 均为整数,r1 为数学值,使得 r1 = ToRawPrecisionFn(n1, e1, p),满足 r1xr1 最大。
    2. n2e2 均为整数,r2 为数学值,使得 r2 = ToRawPrecisionFn(n2, e2, p),满足 r2xr2 最小。
    3. xFinalApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode)。
    4. 如果 xFinalr1,则
      1. nn1
      2. ee1
    5. 否则,
      1. nn2
      2. ee2
    6. mn 的十进制表示数字(按顺序,无前导零)组成的字符串。
  4. 如果 e ≥ (p - 1),则
    1. m 设为 字符串连接(m, e - p + 1 个 0x0030(数字零))。
    2. inte + 1。
  5. 否则如果 e ≥ 0,则
    1. m 设为 字符串连接(前 e + 1 个码元, 0x002E(句点), 剩余 p - (e + 1) 个码元)。
    2. inte + 1。
  6. 否则,
    1. 断言e < 0。
    2. m 设为 字符串连接("0.", –(e + 1) 个 0x0030(数字零), m)。
    3. int 为 1。
  7. 如果 m 包含 0x002E(句点),且 maxPrecision > minPrecision,则
    1. cutmaxPrecision - minPrecision
    2. 重复,当 cut > 0 且 m 的最后一个码元为 0x0030(数字零)时,
      1. 移除 m 的最后一个码元。
      2. cut 设为 cut - 1。
    3. 如果 m 的最后一个码元为 0x002E(句点),则
      1. 移除 m 的最后一个码元。
  8. 返回 Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: ep+1 }。

16.5.9 ToRawFixed ( x, minFraction, maxFraction, roundingIncrement, unsignedRoundingMode )

抽象操作 ToRawFixed 接收参数 x(一个非负数学值)、minFraction(一个整数,取值范围为 0 到 100)、maxFraction(一个整数,取值范围为 0 到 100)、roundingIncrement(一个整数)、unsignedRoundingMode(一个取自表 29 Unsigned Rounding Mode 列的规范类型或 undefined),返回一个Record,字段包括 [[FormattedString]](字符串)、[[RoundedNumber]](数学值)、[[IntegerDigitsCount]](整数)、[[RoundingMagnitude]](整数)。

此操作涉及求解下列方程,输入为整数时返回有效的数学值

ToRawFixedFn(n, f) = n × 10f

调用时执行以下步骤:

  1. fmaxFraction
  2. n1 为整数,r1 为数学值,使得 r1 = ToRawFixedFn(n1, f),满足 n1 roundingIncrement = 0r1xr1 最大。
  3. n2 为整数,r2 为数学值,使得 r2 = ToRawFixedFn(n2, f),满足 n2 roundingIncrement = 0r2xr2 最小。
  4. xFinalApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode)。
  5. 如果 xFinalr1,令 nn1。否则令 nn2
  6. 如果 n = 0,令 m"0"。否则令 mn 的十进制表示数字(按顺序,无前导零)组成的字符串。
  7. 如果 f ≠ 0,则
    1. km 的长度。
    2. 如果 kf,则
      1. zf + 1 - k 个 0x0030(数字零)组成的字符串。
      2. m 设为 字符串连接(z, m)。
      3. kf + 1。
    3. am 的前 k - f 个码元,b 为剩余 f 个码元。
    4. m 设为 字符串连接(a, ".", b)。
    5. inta 的长度。
  8. 否则,
    1. intm 的长度。
  9. cutmaxFraction - minFraction
  10. 重复,当 cut > 0 且 m 的最后一个码元为 0x0030(数字零)时,
    1. 移除 m 的最后一个码元。
    2. cut 设为 cut - 1。
  11. 如果 m 的最后一个码元为 0x002E(句点),则
    1. 移除 m 的最后一个码元。
  12. 返回 Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: –f }。
规范可选

16.5.10 UnwrapNumberFormat ( nf )

抽象操作 UnwrapNumberFormat 接收参数 nf(一个ECMAScript 语言值),返回一个正常完成,包含一个ECMAScript 语言值或一个抛出完成。 它返回输入对象的 NumberFormat 实例,其值要么是自身,要么是 %Intl.NumberFormat% 按照规范可选 构造函数模式 4.3 注 1 关联的值。调用时执行以下步骤:

  1. 如果 nf 不是对象,则抛出 TypeError 异常。
  2. 如果 nf 不具有 [[InitializedNumberFormat]] 内部槽,并且 ?OrdinaryHasInstance(%Intl.NumberFormat%, nf) 为 true,则
    1. 返回 ?Get(nf, %Intl%.[[FallbackSymbol]])。
  3. 返回 nf

16.5.11 GetNumberFormatPattern ( numberFormat, x )

抽象操作 GetNumberFormatPattern 接收参数 numberFormat(一个 Intl.NumberFormat)和 x(一个Intl 数学值),返回一个字符串。 它会考虑数字格式对象中已解析的单位相关选项,以及正在格式化的最终缩放和舍入后的数字(一个Intl 数学值),并返回一个模式字符串,该字符串如16.2.3所述。 调用时执行如下步骤:

  1. resolvedLocaleDatanumberFormat.[[LocaleData]]
  2. patternsresolvedLocaleData.[[patterns]]
  3. 断言patterns 是一个Record (见 16.2.3)。
  4. stylenumberFormat.[[Style]]
  5. 如果 style"percent",则
    1. patterns 设为 patterns.[[percent]]
  6. 否则如果 style"unit",则
    1. unitnumberFormat.[[Unit]]
    2. unitDisplaynumberFormat.[[UnitDisplay]]
    3. patterns 设为 patterns.[[unit]]
    4. 如果 patterns 没有字段 [[<unit>]],则
      1. unit 设为 "fallback"
    5. patterns 设为 patterns.[[<unit>]]。
    6. patterns 设为 patterns.[[<unitDisplay>]]。
  7. 否则如果 style"currency",则
    1. currencynumberFormat.[[Currency]]
    2. currencyDisplaynumberFormat.[[CurrencyDisplay]]
    3. currencySignnumberFormat.[[CurrencySign]]
    4. patterns 设为 patterns.[[currency]]
    5. 如果 patterns 没有字段 [[<currency>]],则
      1. currency 设为 "fallback"
    6. patterns 设为 patterns.[[<currency>]]。
    7. patterns 设为 patterns.[[<currencyDisplay>]]。
    8. patterns 设为 patterns.[[<currencySign>]]。
  8. 否则,
    1. 断言style"decimal"
    2. patterns 设为 patterns.[[decimal]]
  9. 如果 xnegative-infinity,则
    1. categorynegative-non-zero
  10. 否则如果 xnegative-zero,则
    1. categorynegative-zero
  11. 否则如果 xnot-a-number,则
    1. categorypositive-zero
  12. 否则如果 xpositive-infinity,则
    1. categorypositive-non-zero
  13. 否则,
    1. 断言x 是一个数学值
    2. 如果 x < 0,则
      1. categorynegative-non-zero
    3. 否则如果 x > 0,则
      1. categorypositive-non-zero
    4. 否则,
      1. categorypositive-zero
  14. signDisplaynumberFormat.[[SignDisplay]]
  15. 如果 signDisplay"never",则
    1. patternpatterns.[[zeroPattern]]
  16. 否则如果 signDisplay"auto",则
    1. 如果 categorypositive-non-zeropositive-zero,则
      1. patternpatterns.[[zeroPattern]]
    2. 否则,
      1. patternpatterns.[[negativePattern]]
  17. 否则如果 signDisplay"always",则
    1. 如果 categorypositive-non-zeropositive-zero,则
      1. patternpatterns.[[positivePattern]]
    2. 否则,
      1. patternpatterns.[[negativePattern]]
  18. 否则如果 signDisplay"exceptZero",则
    1. 如果 categorypositive-zeronegative-zero,则
      1. patternpatterns.[[zeroPattern]]
    2. 否则如果 categorypositive-non-zero,则
      1. patternpatterns.[[positivePattern]]
    3. 否则,
      1. patternpatterns.[[negativePattern]]
  19. 否则,
    1. 断言signDisplay"negative"
    2. 如果 categorynegative-non-zero,则
      1. patternpatterns.[[negativePattern]]
    3. 否则,
      1. patternpatterns.[[zeroPattern]]
  20. 返回 pattern

16.5.12 GetNotationSubPattern ( numberFormat, exponent )

抽象操作 GetNotationSubPattern 接收参数 numberFormat(一个 Intl.NumberFormat)、exponent(一个整数),返回一个字符串。 它会考虑已解析的记号和 exponent,并返回如16.2.3所述的记号子模式字符串。 调用时执行如下步骤:

  1. resolvedLocaleDatanumberFormat.[[LocaleData]]
  2. notationSubPatternsresolvedLocaleData.[[notationSubPatterns]]
  3. 断言notationSubPatterns 是一个Record (见 16.2.3)。
  4. notationnumberFormat.[[Notation]]
  5. 如果 notation"scientific"notation"engineering",则
    1. 返回 notationSubPatterns.[[scientific]]
  6. 否则如果 exponent 不等于 0,则
    1. 断言notation"compact"
    2. compactDisplaynumberFormat.[[CompactDisplay]]
    3. compactPatternsnotationSubPatterns.[[compact]].[[<compactDisplay>]]。
    4. 返回 compactPatterns.[[<exponent>]]。
  7. 否则,
    1. 返回 "{number}"

16.5.13 ComputeExponent ( numberFormat, x )

抽象操作 ComputeExponent 接收参数 numberFormat(一个 Intl.NumberFormat)、x(一个数学值),返回一个整数。 它会根据数字格式设置计算一个用于缩放 x 的指数(10 的幂)。 处理如 999 舍入到 1000 等情况,需要不同的指数。 调用时执行如下步骤:

  1. 如果 x = 0,则
    1. 返回 0。
  2. 如果 x < 0,则
    1. x = -x
  3. magnitudex 的以 10 为底对数,向下取整为最近的整数
  4. exponentComputeExponentForMagnitude(numberFormat, magnitude)。
  5. xx × 10-exponent
  6. formatNumberResultFormatNumericToString(numberFormat, x)。
  7. 如果 formatNumberResult.[[RoundedNumber]] = 0,则
    1. 返回 exponent
  8. newMagnitudeformatNumberResult.[[RoundedNumber]] 的以 10 为底对数,向下取整为最近的整数
  9. 如果 newMagnitudemagnitude - exponent,则
    1. 返回 exponent
  10. 返回 ComputeExponentForMagnitude(numberFormat, magnitude + 1)。

16.5.14 ComputeExponentForMagnitude ( numberFormat, magnitude )

抽象操作 ComputeExponentForMagnitude 接收参数 numberFormat(一个 Intl.NumberFormat)、magnitude(一个整数),返回一个整数。 它会根据当前语言环境和所需记号(科学、工程或紧缩),计算用于缩放具有指定数量级(最高有效位的十的幂)的数字的指数。 调用时执行如下步骤:

  1. notationnumberFormat.[[Notation]]
  2. 如果 notation"standard",则
    1. 返回 0。
  3. 否则如果 notation"scientific",则
    1. 返回 magnitude
  4. 否则如果 notation"engineering",则
    1. thousands 为最大的不大于 magnitude / 3 的整数
    2. 返回 thousands × 3。
  5. 否则,
    1. 断言notation"compact"
    2. exponent 为一个ILD 整数,用于当前语言环境下紧缩记号数字的缩放。
    3. 返回 exponent

16.5.15 Runtime Semantics: StringIntlMV

语法定向操作 StringIntlMV 无参数。

StringNumericLiteral 转换为 Number 值的过程整体类似于 NumericValue 的确定方式 (见12.9.3), 但部分细节不同。

其按如下产生式分段定义:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. 返回 0。
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. 返回 StringIntlMVStrNumericLiteral
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. 返回 NonDecimalIntegerLiteral 的 MV。
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. aStringIntlMVStrUnsignedDecimalLiteral
  2. 如果 a 为 0,返回 negative-zero
  3. 如果 apositive-infinity,返回 negative-infinity
  4. 返回 -a
StrUnsignedDecimalLiteral ::: Infinity
  1. 返回 positive-infinity
StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigitsopt ExponentPartopt
  1. a 为第一个 DecimalDigits 的 MV。
  2. 如果第二个 DecimalDigits 存在,则
    1. b 为第二个 DecimalDigits 的 MV。
    2. n 为第二个 DecimalDigits 的码点数。
  3. 否则,
    1. b 为 0。
    2. n 为 0。
  4. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则令 e 为 0。
  5. 返回 (a + (b × 10-n)) × 10e
StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPartopt
  1. bDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则令 e 为 0。
  3. nDecimalDigits 的码点数。
  4. 返回 b × 10e - n
StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPartopt
  1. aDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则令 e 为 0。
  3. 返回 a × 10e

16.5.16 ToIntlMathematicalValue ( value )

抽象操作 ToIntlMathematicalValue 接收参数 value(一个ECMAScript 语言值),返回一个正常完成,包含一个Intl 数学值或一个抛出完成。 它返回将 value 转换为Intl 数学值的结果,该值是一个数学值,同时包括 positive-infinitynegative-infinitynot-a-numbernegative-zero。 此抽象操作类似于 7.1.3,但可返回数学值而不是 Number 或 BigInt,因此能精确表示小数值。 调用时执行如下步骤:

  1. primValue 为 ?ToPrimitive(value, number)。
  2. 如果 primValue 是 BigInt,返回 (primValue)。
  3. 如果 primValue 是字符串,则
    1. strprimValue
  4. 否则,
    1. x 为 ?ToNumber(primValue)。
    2. 如果 x-0𝔽,返回 negative-zero
    3. strNumber::toString(x, 10)。
  5. textStringToCodePoints(str)。
  6. literalParseText(text, StringNumericLiteral)。
  7. 如果 literal 是一个错误的List,返回 not-a-number
  8. intlMVStringIntlMVliteral
  9. 如果 intlMV 是一个数学值,则
    1. roundedRoundMVResult(abs(intlMV))。
    2. 如果 rounded+∞𝔽intlMV < 0,返回 negative-infinity
    3. 如果 rounded+∞𝔽,返回 positive-infinity
    4. 如果 rounded+0𝔽intlMV < 0,返回 negative-zero
    5. 如果 rounded+0𝔽,返回 0。
  10. 返回 intlMV

16.5.17 GetUnsignedRoundingMode ( roundingMode, sign )

抽象操作 GetUnsignedRoundingMode 接收参数 roundingMode(一个舍入模式)和 signnegativepositive),返回表 29 Unsigned Rounding Mode 列的规范类型。它返回应用于数字绝对值的舍入模式,使结果与对有符号值(负值为 signnegative,否则为正)应用 roundingMode 的结果一致。调用时执行如下步骤:

  1. 返回 表 29中 Identifier 列为 roundingMode、Sign 列为 sign 的行 Unsigned Rounding Mode 列的规范类型。
表 29:舍入模式到无符号舍入模式的转换
标识符 符号 无符号舍入模式
"ceil" positive infinity
negative zero
"floor" positive zero
negative infinity
"expand" positive infinity
negative infinity
"trunc" positive zero
negative zero
"halfCeil" positive half-infinity
negative half-zero
"halfFloor" positive half-zero
negative half-infinity
"halfExpand" positive half-infinity
negative half-infinity
"halfTrunc" positive half-zero
negative half-zero
"halfEven" positive half-even
negative half-even

16.5.18 ApplyUnsignedRoundingMode ( x, r1, r2, unsignedRoundingMode )

抽象操作 ApplyUnsignedRoundingMode 接收参数 x(一个数学值)、r1(一个数学值)、r2(一个数学值)、unsignedRoundingMode(一个取自表 29 Unsigned Rounding Mode 列的规范类型或undefined),返回一个数学值。它会考虑 xr1 为下界,r2 为上界,并根据 unsignedRoundingMode 返回 r1r2。调用时执行如下步骤:

  1. 如果 xr1,返回 r1
  2. 断言r1 < x < r2
  3. 断言unsignedRoundingModeundefined
  4. 如果 unsignedRoundingModezero,返回 r1
  5. 如果 unsignedRoundingModeinfinity,返回 r2
  6. d1xr1
  7. d2r2x
  8. 如果 d1 < d2,返回 r1
  9. 如果 d2 < d1,返回 r2
  10. 断言d1 等于 d2
  11. 如果 unsignedRoundingModehalf-zero,返回 r1
  12. 如果 unsignedRoundingModehalf-infinity,返回 r2
  13. 断言unsignedRoundingModehalf-even
  14. cardinality(r1 / (r2r1)) 2
  15. 如果 cardinality 为 0,返回 r1
  16. 返回 r2

16.5.19 PartitionNumberRangePattern ( numberFormat, x, y )

抽象操作 PartitionNumberRangePattern 接收参数 numberFormat(一个 Intl.NumberFormat)、x(一个Intl 数学值)、y(一个Intl 数学值),返回一个正常完成,包含一个List,其中元素为包含字段 [[Type]](字符串)、[[Value]](字符串)、[[Source]](字符串)的Records,或一个抛出完成。它根据 xynumberFormat 的格式化选项,创建本地化数字区间的分段。调用时执行如下步骤:

  1. 如果 xnot-a-numberynot-a-number,则抛出 RangeError 异常。
  2. xResultPartitionNumberPattern(numberFormat, x)。
  3. yResultPartitionNumberPattern(numberFormat, y)。
  4. 如果 FormatNumeric(numberFormat, x) 与 FormatNumeric(numberFormat, y) 相同,则
    1. appxResultFormatApproximately(numberFormat, xResult)。
    2. appxResult 的每个元素 r,执行:
      1. r.[[Source]] 设为 "shared"
    3. 返回 appxResult
  5. result 为一个新的空List
  6. xResult 的每个元素 r,执行:
    1. Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "startRange" } 追加到 result
  7. rangeSeparator 为一个ILND 字符串值,用于分隔两个数字。
  8. Record { [[Type]]: "literal", [[Value]]: rangeSeparator, [[Source]]: "shared" } 追加到 result
  9. yResult 的每个元素 r,执行:
    1. Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "endRange" } 追加到 result
  10. 返回 CollapseNumberRange(numberFormat, result)。

16.5.20 FormatApproximately ( numberFormat, result )

抽象操作 FormatApproximately 接收参数 numberFormat(一个 Intl.NumberFormat)、result(一个List,其中元素为包含字段 [[Type]](字符串)、[[Value]](字符串)的Records),返回一个List,其中元素为包含字段 [[Type]](字符串)、[[Value]](字符串)的Records。它会修改 result,后者必须是如 PartitionNumberPattern 所述的List,通过添加一个表示约等号的Record,该符号可能取决于 numberFormat。调用时执行如下步骤:

  1. approximatelySign 为一个ILND 字符串值,用于表示数字约等。
  2. 如果 approximatelySign 非空,则在 result 的一个ILND 索引处插入 Record { [[Type]]: "approximatelySign", [[Value]]: approximatelySign }。例如,如果 numberFormat[[Locale]]"en-US"[[NumberingSystem]]"latn"[[Style]]"decimal",则新的Record 可能插入到 result 的第一个元素之前。
  3. 返回 result

16.5.21 CollapseNumberRange ( numberFormat, result )

实现自定义 抽象操作 CollapseNumberRange 接收参数 numberFormat(一个 Intl.NumberFormat)和 result(一个List, 元素为包含字段 [[Type]](字符串)、[[Value]](字符串)、[[Source]](字符串)的Records),并返回一个List, 元素为包含字段 [[Type]](字符串)、[[Value]](字符串)、[[Source]](字符串)的Records。它会根据当前语言环境及 numberFormat 的格式化选项,对 result(必须是List,由PartitionNumberRangePattern构造)进行修改,通过去除冗余信息、解决内部不一致、必要时替换字符、必要时插入空格。然后返回处理后的List。 该算法为ILND,但不得引入歧义,使得 Intl.NumberFormat.prototype.formatRange ( start, end ) 的参数 List « start1, end1 » 的结果等于参数 List « start2, end2 » 的结果,仅当对这两个参数使用永远返回未修改 result 的 CollapseNumberRange 实现,其结果也相等时才允许。

例如,一个实现可以在区间分隔符后移除表示货币符号的Record,将表示 "$3–$5"results List 转换为表示 "$3–5"List

实现还可以为语法正确性修改Record[[Value]] 字段;例如,将表示 "0.5 miles–1 mile"results List 转换为表示 "0.5–1 miles"List

返回未修改的 result 可保证是 CollapseNumberRange 的正确实现。

16.5.22 FormatNumericRange ( numberFormat, x, y )

抽象操作 FormatNumericRange 接收参数 numberFormat(一个 Intl.NumberFormat)、x(一个Intl 数学值)、y(一个Intl 数学值),返回一个正常完成,包含字符串,或一个抛出完成。调用时执行如下步骤:

  1. parts 为 ?PartitionNumberRangePattern(numberFormat, x, y)。
  2. result 为空字符串。
  3. parts 的每个元素 part,执行:
    1. result 设为 字符串连接(result, part.[[Value]])。
  4. 返回 result

16.5.23 FormatNumericRangeToParts ( numberFormat, x, y )

抽象操作 FormatNumericRangeToParts 接收参数 numberFormat(一个 Intl.NumberFormat)、x(一个Intl 数学值)、y(一个Intl 数学值),返回一个正常完成,包含数组,或一个抛出完成。调用时执行如下步骤:

  1. parts 为 ?PartitionNumberRangePattern(numberFormat, x, y)。
  2. result 为 !ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个元素 part,执行:
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 !CreateDataPropertyOrThrow(O, "type", part.[[Type]])。
    3. 执行 !CreateDataPropertyOrThrow(O, "value", part.[[Value]])。
    4. 执行 !CreateDataPropertyOrThrow(O, "source", part.[[Source]])。
    5. 执行 !CreateDataPropertyOrThrow(result, !ToString(𝔽(n)), O)。
    6. n 加 1。
  5. 返回 result

17 PluralRules 对象

17.1 Intl.PluralRules 构造函数

Intl.PluralRules 构造函数

  • %Intl.PluralRules%
  • Intl 对象"PluralRules" 属性的初始值。

所有 服务构造函数属性的共同行为,见 9.1

17.1.1 Intl.PluralRules ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.PluralRules 函数时,执行如下步骤:

  1. 如果 NewTarget 是 undefined,则抛出 TypeError 异常。
  2. pluralRules 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.PluralRules.prototype%", « [[InitializedPluralRules]], [[Locale]], [[Type]], [[Notation]], [[CompactDisplay]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[RoundingIncrement]], [[RoundingMode]], [[ComputedRoundingPriority]], [[TrailingZeroDisplay]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.PluralRules%, %Intl.PluralRules%.[[LocaleData]], locales, options, « coerce-options »)。
  4. 设置 optionsoptionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. 设置 pluralRules.[[Locale]]r.[[Locale]]
  7. t 为 ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal")。
  8. 设置 pluralRules.[[Type]]t
  9. notation 为 ? GetOption(options, "notation", string, « "standard", "scientific", "engineering", "compact" », "standard")。
  10. 设置 pluralRules.[[Notation]]notation
  11. compactDisplay 为 ? GetOption(options, "compactDisplay", string, « "short", "long" », "short")。
  12. 设置 pluralRules.[[CompactDisplay]]compactDisplay
  13. 执行 ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3, notation)。
  14. 返回 pluralRules

17.2 Intl.PluralRules 构造函数的属性

Intl.PluralRules 构造函数

  • 有一个 [[Prototype]] 内部槽,其值为 %Function.prototype%
  • 具有以下属性:

17.2.1 Intl.PluralRules.prototype

Intl.PluralRules.prototype 的值为 %Intl.PluralRules.prototype%

此属性的属性值为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

17.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行如下步骤:

  1. availableLocales%Intl.PluralRules%.[[AvailableLocales]]
  2. requestedLocales 为 ?CanonicalizeLocaleList(locales)。
  3. 返回 ?FilterLocales(availableLocales, requestedLocales, options)。

17.2.3 内部槽

[[AvailableLocales]] 内部槽的值为 实现自定义,受 9.1 约束。

[[RelevantExtensionKeys]] 内部槽的值为 « »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « »。

注 1
Unicode Technical Standard #35 Part 1 Core, Section 3.6.1 Key and Type Definitions 未描述与复数化过程相关的语言环境扩展键。

[[LocaleData]] 内部槽的值为 实现自定义,受 9.1 约束。

注 2
建议实现使用 Common Locale Data Repository(CLDR,https://cldr.unicode.org/)提供的语言环境数据。

17.3 Intl.PluralRules 原型对象的属性

Intl.PluralRules 原型对象

  • %Intl.PluralRules.prototype%
  • 是一个普通对象
  • 不是 Intl.PluralRules 实例,也没有 [[InitializedPluralRules]] 内部槽或 Intl.PluralRules 实例对象的其他内部槽。
  • 有一个 [[Prototype]] 内部槽,其值为 %Object.prototype%

17.3.1 Intl.PluralRules.prototype.constructor

Intl.PluralRules.prototype.constructor 的初始值为 %Intl.PluralRules%

17.3.2 Intl.PluralRules.prototype.resolvedOptions ( )

此函数用于访问对象初始化时计算得到的语言环境与选项。

  1. prthis 值。
  2. 执行 ?RequireInternalSlot(pr, [[InitializedPluralRules]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. pluralCategories 为一个字符串List,包括所选语言环境 pr.[[Locale]]PluralRuleSelect 所有可能的结果,并按如下顺序排序:"zero""one""two""few""many""other"
  5. 按表序对 表 30 的每一行(除表头行)执行:
    1. p 为当前行 Property 列的值。
    2. 如果 p"pluralCategories",则
      1. vCreateArrayFromList(pluralCategories)。
    3. 否则,
      1. vpr 的内部槽中,名称为当前行 Internal Slot 的槽的值。
    4. 如果 vundefined,则
      1. 如果当前行有 Conversion 值,则
        1. 断言:当前行 Conversion 值为 number
        2. v 设为 𝔽(v)。
      2. 执行 !CreateDataPropertyOrThrow(options, p, v)。
  6. 返回 options
表 30:PluralRules 实例的已解析选项
内部插槽 属性 转换方式
[[Locale]] "locale"
[[Type]] "type"
[[Notation]] "notation"
[[CompactDisplay]] "compactDisplay"
[[MinimumIntegerDigits]] "minimumIntegerDigits" number
[[MinimumFractionDigits]] "minimumFractionDigits" number
[[MaximumFractionDigits]] "maximumFractionDigits" number
[[MinimumSignificantDigits]] "minimumSignificantDigits" number
[[MaximumSignificantDigits]] "maximumSignificantDigits" number
"pluralCategories"
[[RoundingIncrement]] "roundingIncrement" number
[[RoundingMode]] "roundingMode"
[[ComputedRoundingPriority]] "roundingPriority"
[[TrailingZeroDisplay]] "trailingZeroDisplay"

17.3.3 Intl.PluralRules.prototype.select ( value )

当以参数 value 调用 select 方法时,执行如下步骤:

  1. prthis 值。
  2. 执行 ?RequireInternalSlot(pr, [[InitializedPluralRules]])。
  3. n 为 ?ToNumber(value)。
  4. 返回 ResolvePlural(pr, n).[[PluralCategory]]

17.3.4 Intl.PluralRules.prototype.selectRange ( start, end )

当以参数 startend 调用 selectRange 方法时,执行如下步骤:

  1. prthis 值。
  2. 执行 ?RequireInternalSlot(pr, [[InitializedPluralRules]])。
  3. 如果 startundefinedendundefined,则抛出 TypeError 异常。
  4. x 为 ?ToNumber(start)。
  5. y 为 ?ToNumber(end)。
  6. 返回 ?ResolvePluralRange(pr, x, y)。

17.3.5 Intl.PluralRules.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.PluralRules"

此属性的属性值为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

17.4 Intl.PluralRules 实例的属性

Intl.PluralRules 实例是普通对象,继承自 %Intl.PluralRules.prototype% 的属性。

Intl.PluralRules 实例有一个 [[InitializedPluralRules]] 内部槽。

Intl.PluralRules 实例还具有一些由 Intl.PluralRules 构造函数 计算出的内部槽:

  • [[Locale]] 是字符串,其值为用于复数规则本地化的语言环境 language tag
  • [[Type]] 是字符串值之一:"cardinal""ordinal",用于标识所用复数规则。
  • [[Notation]] 是字符串值之一:"standard""scientific""engineering""compact",用于标识使用的记号。
  • [[CompactDisplay]] 是字符串值 "short""long" 之一,用于指定在使用 "compact" 记数法格式化时,紧凑记数法的前后缀是以短格式("5K")还是长格式("5 thousand")显示,因为在某些情况下这会影响复数形式的选择。仅当 [[Notation]] 的值为 "compact" 时才会使用此属性。
  • [[MinimumIntegerDigits]] 是非负整数,表示要使用的最小整数位数。
  • [[MinimumFractionDigits]][[MaximumFractionDigits]] 是非负整数,表示要使用的最小和最大小数位数。必要时数字会四舍五入或用零补齐。
  • [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 是正整数,表示要使用的最小和最大有效数字。两者要么都不存在,要么都存在;如存在则覆盖最小和最大整数位数及小数位数。
  • [[RoundingType]]fraction-digitssignificant-digitsmore-precisionless-precision,表示使用哪种舍入策略,详见 16.4
  • [[ComputedRoundingPriority]] 是字符串值之一:"auto""morePrecision""lessPrecision"。仅在 17.3.2 中用于将 [[RoundingType]] 转换回有效的 "roundingPriority" 选项。
  • [[RoundingIncrement]] 是一个整数,可整除 10、100、1000 或 10000,表示舍入时采用的增量。例如,当 [[MaximumFractionDigits]] 为 2,[[RoundingIncrement]] 为 5 时,数字将按最接近的 0.05 四舍五入(即 "nickel rounding")。
  • [[RoundingMode]] 用于标识所用舍入模式
  • [[TrailingZeroDisplay]] 是字符串值之一:"auto""stripIfInteger",表示当格式化结果为整数(即无非零小数位)时是否去除尾随零。

17.5 PluralRules 对象的抽象操作

17.5.1 PluralRuleSelect ( locale, type, notation, compactDisplay, s )

实现定义的抽象操作 PluralRuleSelect 接受参数 locale(一个语言标签)、type"cardinal""ordinal")、notation(一个字符串)、compactDisplay"short""long"),以及 s(一个十进制字符串),并返回 "zero""one""two""few""many""other"。返回的字符串根据 typenotationcompactDisplay,针对相应的 locale,描述 s 的复数类别。

17.5.2 ResolvePlural ( pluralRules, n )

抽象操作 ResolvePlural 接受参数 pluralRules(一个 Intl.PluralRules)和 n(一个 Number),返回一个带有字段 [[PluralCategory]]"zero""one""two""few""many""other")和 [[FormattedString]](一个字符串)的 Record。返回的 Record 包含两个字符串值的字段,分别根据有效语言环境和 pluralRules 的选项描述 n[[PluralCategory]] 用于标识其 复数类别[[FormattedString]] 包含其格式化表示。调用时执行以下步骤:

  1. 如果 n 不是 有限数字,则
    1. s 为 ! ToString(n)。
    2. 返回 Record { [[PluralCategory]]: "other", [[FormattedString]]: s }。
  2. resFormatNumericToString(pluralRules, (n))。
  3. sres.[[FormattedString]]
  4. localepluralRules.[[Locale]]
  5. typepluralRules.[[Type]]
  6. notationpluralRules.[[Notation]]
  7. compactDisplaypluralRules.[[CompactDisplay]]
  8. pPluralRuleSelect(locale, type, notation, compactDisplay, s)。
  9. 返回 Record { [[PluralCategory]]: p, [[FormattedString]]: s }。

17.5.3 PluralRuleSelectRange ( locale, type, notation, compactDisplay, xp, yp )

实现定义的抽象操作 PluralRuleSelectRange 接受参数 locale(一个语言标签)、type"cardinal""ordinal")、notation(一个字符串)、compactDisplay"short""long")、xp"zero""one""two""few""many""other"),以及 yp"zero""one""two""few""many""other"),返回 "zero""one""two""few""many""other"。它执行一个由实现决定的算法,将 复数类别字符串值 xpyp(分别描述区间的起点和终点)映射为针对相应 localetypenotationcompactDisplay 表示的区间整体的复数形式已解析的字符串值,或者字符串值 "other"

17.5.4 ResolvePluralRange ( pluralRules, x, y )

抽象操作 ResolvePluralRange 接受参数 pluralRules(一个 Intl.PluralRules)、x(一个 Number)、y(一个 Number),返回一个 正常完成,其中包含 "zero""one""two""few""many""other",或者一个 抛出完成。返回的字符串值表示从 xy 的区间的复数形式,依据有效语言环境和 pluralRules 的选项。调用时执行以下步骤:

  1. 如果 xNaNyNaN,则抛出 RangeError 异常。
  2. xpResolvePlural(pluralRules, x)。
  3. ypResolvePlural(pluralRules, y)。
  4. 如果 xp.[[FormattedString]] 等于 yp.[[FormattedString]],则
    1. 返回 xp.[[PluralCategory]]
  5. localepluralRules.[[Locale]]
  6. typepluralRules.[[Type]]
  7. notationpluralRules.[[Notation]]
  8. compactDisplaypluralRules.[[CompactDisplay]]
  9. 返回 PluralRuleSelectRange(locale, type, notation, compactDisplay, xp.[[PluralCategory]], yp.[[PluralCategory]])。

18 RelativeTimeFormat 对象

18.1 Intl.RelativeTimeFormat 构造函数

Intl.RelativeTimeFormat 构造函数

  • %Intl.RelativeTimeFormat%
  • Intl 对象"RelativeTimeFormat" 属性的初始值。

服务构造函数属性的共同行为,见 9.1

18.1.1 Intl.RelativeTimeFormat ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.RelativeTimeFormat 函数时,执行如下步骤:

  1. 如果 NewTarget 为 undefined,抛出 TypeError 异常。
  2. relativeTimeFormat 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.RelativeTimeFormat.prototype%", « [[InitializedRelativeTimeFormat]], [[Locale]], [[LocaleData]], [[Style]], [[Numeric]], [[NumberFormat]], [[NumberingSystem]], [[PluralRules]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.RelativeTimeFormat%, %Intl.RelativeTimeFormat%.[[LocaleData]], locales, options, « coerce-options »)。
  4. options 设为 optionsResolution.[[Options]]
  5. roptionsResolution.[[ResolvedLocale]]
  6. localer.[[Locale]]
  7. relativeTimeFormat.[[Locale]] 设为 locale
  8. relativeTimeFormat.[[LocaleData]] 设为 r.[[LocaleData]]
  9. relativeTimeFormat.[[NumberingSystem]] 设为 r.[[nu]]
  10. style 为 ? GetOption(options, "style", string, « "long", "short", "narrow" », "long")。
  11. relativeTimeFormat.[[Style]] 设为 style
  12. numeric 为 ? GetOption(options, "numeric", string, « "always", "auto" », "always")。
  13. relativeTimeFormat.[[Numeric]] 设为 numeric
  14. nfOptionsOrdinaryObjectCreate(null)。
  15. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", relativeTimeFormat.[[NumberingSystem]])。
  16. relativeTimeFormat.[[NumberFormat]] 为 ! Construct(%Intl.NumberFormat%, « locale, nfOptions »)。
  17. relativeTimeFormat.[[PluralRules]] 为 ! Construct(%Intl.PluralRules%, « locale »)。
  18. 返回 relativeTimeFormat

18.2 Intl.RelativeTimeFormat 构造函数的属性

Intl.RelativeTimeFormat 构造函数

18.2.1 Intl.RelativeTimeFormat.prototype

Intl.RelativeTimeFormat.prototype 的值为 %Intl.RelativeTimeFormat.prototype%

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

18.2.2 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行如下步骤:

  1. availableLocales%Intl.RelativeTimeFormat%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocales, requestedLocales, options)。

18.2.3 内部槽

[[AvailableLocales]] 内部槽的值为 实现自定义,受 9.1 的约束。

[[RelevantExtensionKeys]] 内部槽的值为 « "nu" »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « { [[Key]]: "nu", [[Property]]: "numberingSystem" } »。

注 1
Unicode Technical Standard #35 Part 1 Core, Section 3.6.1 Key and Type Definitions 描述了一个与相对时间格式相关的语言环境扩展键:用于数字系统(已格式化数字)的 "nu"

[[LocaleData]] 内部槽的值为 实现自定义,受 9.1 以及以下附加约束(对所有语言环境值 locale)的约束:

  • [[LocaleData]].[[<locale>]] 具有字段 "second""minute""hour""day""week""month""quarter""year"。还可以存在附加字段,其名称为上述名称与 "-narrow""-short" 拼接得到。对应这些字段的值为Records, 包含两类字段:
    • "future""past" 字段,这些是Records, 每个包含对 locale 相关的各复数类别的字段。对应这些字段的值是一个模式,其中可以包含 "{0}" 以替换为格式化的数字。
    • 可选的附加字段,其键为某个 Number 经 ToString 的结果,值为不作为模板处理的字面字符串。
  • List 中任一语言环境字段的 [[LocaleData]]"nu" 字段的值不得包含 "native""traditio""finance"
注 2
建议实现使用 Common Locale Data Repository(CLDR,https://cldr.unicode.org/)提供的语言环境数据。

18.3 Intl.RelativeTimeFormat 原型对象的属性

Intl.RelativeTimeFormat 原型对象

  • %Intl.RelativeTimeFormat.prototype%
  • 是一个普通对象
  • 不是 Intl.RelativeTimeFormat 实例,也不具有 [[InitializedRelativeTimeFormat]] 内部槽或 Intl.RelativeTimeFormat 实例对象的其他内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

18.3.1 Intl.RelativeTimeFormat.prototype.constructor

Intl.RelativeTimeFormat.prototype.constructor 的初始值为 %Intl.RelativeTimeFormat%

18.3.2 Intl.RelativeTimeFormat.prototype.resolvedOptions ( )

此函数用于访问对象初始化期间计算得到的语言环境和选项。

  1. relativeTimeFormatthis 值。
  2. 执行 ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序对 表 31 的每一行(除表头)执行:
    1. p 为当前行的 Property 值。
    2. vrelativeTimeFormat 的内部槽中名称为当前行 Internal Slot 值的槽的值。
    3. 断言vundefined
    4. 执行 ! CreateDataPropertyOrThrow(options, p, v)。
  5. 返回 options
表 31:RelativeTimeFormat 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[Style]] "style"
[[Numeric]] "numeric"
[[NumberingSystem]] "numberingSystem"

18.3.3 Intl.RelativeTimeFormat.prototype.format ( value, unit )

当以参数 valueunit 调用 format 方法时,执行如下步骤:

  1. relativeTimeFormatthis 值。
  2. 执行 ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]])。
  3. value 为 ? ToNumber(value)。
  4. unit 为 ? ToString(unit)。
  5. 返回 ? FormatRelativeTime(relativeTimeFormat, value, unit)。

18.3.4 Intl.RelativeTimeFormat.prototype.formatToParts ( value, unit )

当以参数 valueunit 调用 formatToParts 方法时,执行如下步骤:

  1. relativeTimeFormatthis 值。
  2. 执行 ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]])。
  3. value 为 ? ToNumber(value)。
  4. unit 为 ? ToString(unit)。
  5. 返回 ? FormatRelativeTimeToParts(relativeTimeFormat, value, unit)。

18.3.5 Intl.RelativeTimeFormat.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.RelativeTimeFormat"

此属性具有特性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

18.4 Intl.RelativeTimeFormat 实例的属性

Intl.RelativeTimeFormat 实例是普通对象,继承自 %Intl.RelativeTimeFormat.prototype% 的属性。

Intl.RelativeTimeFormat 实例具有 [[InitializedRelativeTimeFormat]] 内部槽。

Intl.RelativeTimeFormat 实例还具有由 Intl.RelativeTimeFormat 构造函数 计算的多个内部槽:

  • [[Locale]] 是字符串,其值为用于格式化的语言环境的 language tag
  • [[LocaleData]] 是一个Record,表示实现可用于格式化的数据。它来源于 %Intl.RelativeTimeFormat%.[[LocaleData]] 中与 [[Locale]] 的值或其前缀关联的条目。
  • [[Style]] 是字符串值之一:"long""short""narrow",用于标识所用的相对时间格式样式。
  • [[Numeric]] 是字符串值之一:"always""auto",用于标识数值描述是始终使用,还是仅在没有更具体版本可用时才使用(例如,“1 day ago” 与 “yesterday”)。
  • [[NumberFormat]] 是用于格式化的 Intl.NumberFormat 对象。
  • [[NumberingSystem]] 是字符串,表示用于格式化的 Unicode Number System Identifier
  • [[PluralRules]] 是用于格式化的 Intl.PluralRules 对象。

18.5 RelativeTimeFormat 对象的抽象操作

18.5.1 SingularRelativeTimeUnit ( unit )

抽象操作 SingularRelativeTimeUnit 接收参数 unit(字符串),返回一个正常完成,包含字符串或抛出完成。调用时执行如下步骤:

  1. 如果 unit"seconds",返回 "second"
  2. 如果 unit"minutes",返回 "minute"
  3. 如果 unit"hours",返回 "hour"
  4. 如果 unit"days",返回 "day"
  5. 如果 unit"weeks",返回 "week"
  6. 如果 unit"months",返回 "month"
  7. 如果 unit"quarters",返回 "quarter"
  8. 如果 unit"years",返回 "year"
  9. 如果 unit 不是 "second""minute""hour""day""week""month""quarter""year" 之一,抛出 RangeError 异常。
  10. 返回 unit

18.5.2 PartitionRelativeTimePattern ( relativeTimeFormat, value, unit )

抽象操作 PartitionRelativeTimePattern 接收参数 relativeTimeFormat(一个 Intl.RelativeTimeFormat)、value(数字)、unit(字符串),返回一个正常完成,包含List(其中元素为Records,字段为 [[Type]](字符串)、[[Value]](字符串)和 [[Unit]](字符串或 empty)),或抛出完成。返回的List根据当前语言环境和 relativeTimeFormat 的格式化选项表示 value。调用时执行如下步骤:

  1. 如果 valueNaN+∞𝔽-∞𝔽,抛出 RangeError 异常。
  2. unit 为 ? SingularRelativeTimeUnit(unit)。
  3. fieldsrelativeTimeFormat.[[LocaleData]]
  4. patternsfields.[[<unit>]]。
  5. stylerelativeTimeFormat.[[Style]]
  6. 如果 style"short""narrow",则
    1. keyunit"-"style字符串连接
    2. 如果 fields 具有字段 [[<key>]],将 patterns 设为 fields.[[<key>]]。
  7. 如果 relativeTimeFormat.[[Numeric]]"auto",则
    1. valueString 为 ! ToString(value)。
    2. 如果 patterns 具有字段 [[<valueString>]],则
      1. resultpatterns.[[<valueString>]]。
      2. 返回一个List, 其中包含Record { [[Type]]: "literal", [[Value]]: result, [[Unit]]: empty }。
  8. 如果 value-0𝔽value < -0𝔽,则
    1. tl"past"
  9. 否则,
    1. tl"future"
  10. popatterns.[[<tl>]]。
  11. fvPartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], (value))。
  12. prResolvePlural(relativeTimeFormat.[[PluralRules]], value).[[PluralCategory]]
  13. patternpo.[[<pr>]]。
  14. 返回 MakePartsList(patternunitfv)。

18.5.3 MakePartsList ( pattern, unit, parts )

抽象操作 MakePartsList 接收参数 pattern模式字符串)、unit(字符串)和 parts(一个List,元素为表示格式化 Number 的Records),返回一个List(元素为Records,字段为 [[Type]](字符串)、[[Value]](字符串)和 [[Unit]](字符串或 empty))。调用时执行如下步骤:

  1. patternPartsPartitionPattern(pattern)。
  2. result 为一个新的空List
  3. patternParts 中的每个Record { [[Type]], [[Value]] } patternPart,执行:
    1. 如果 patternPart.[[Type]]"literal",则
      1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]], [[Unit]]: empty } 追加至 result
    2. 否则,
      1. 断言patternPart.[[Type]]"0"
      2. parts 中的每个Record { [[Type]], [[Value]] } part,执行:
        1. Record { [[Type]]: part.[[Type]], [[Value]]: part.[[Value]], [[Unit]]: unit } 追加至 result
  4. 返回 result
示例:
  1. 返回 MakePartsList("AA{0}BB""hour",« Record { [[Type]]: "integer", [[Value]]: "15" } »)。
将返回一个List, 其中包含如下Records « { [[Type]]: "literal", [[Value]]: "AA", [[Unit]]: empty}, { [[Type]]: "integer", [[Value]]: "15", [[Unit]]: "hour"}, { [[Type]]: "literal", [[Value]]: "BB", [[Unit]]: empty} »

18.5.4 FormatRelativeTime ( relativeTimeFormat, value, unit )

抽象操作 FormatRelativeTime 接收参数 relativeTimeFormat(一个 Intl.RelativeTimeFormat)、value(数字)和 unit(字符串),返回一个正常完成,包含字符串或抛出完成。调用时执行如下步骤:

  1. parts 为 ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit)。
  2. result 为空字符串。
  3. parts 中的每个Record { [[Type]], [[Value]], [[Unit]] } part,执行:
    1. result 设为 字符串连接(resultpart.[[Value]])。
  4. 返回 result

18.5.5 FormatRelativeTimeToParts ( relativeTimeFormat, value, unit )

抽象操作 FormatRelativeTimeToParts 接收参数 relativeTimeFormat(一个 Intl.RelativeTimeFormat)、value(数字)和 unit(字符串),返回一个正常完成,包含数组或抛出完成。调用时执行如下步骤:

  1. parts 为 ? PartitionRelativeTimePattern(relativeTimeFormatvalueunit)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 中的每个Record { [[Type]], [[Value]], [[Unit]] } part,执行:
    1. OOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(O"type"part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(O"value"part.[[Value]])。
    4. 如果 part.[[Unit]]empty,则
      1. 执行 ! CreateDataPropertyOrThrow(O"unit"part.[[Unit]])。
    5. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), O)。
    6. n 加 1。
  5. 返回 result

19 Segmenter 对象

19.1 Intl.Segmenter 构造函数

Intl.Segmenter 构造函数

  • %Intl.Segmenter%
  • Intl 对象"Segmenter" 属性的初始值。

服务构造函数属性的共同行为,见 9.1

19.1.1 Intl.Segmenter ( [ locales [ , options ] ] )

当以可选参数 localesoptions 调用 Intl.Segmenter 函数时,执行如下步骤:

  1. 如果 NewTarget 为 undefined,抛出 TypeError 异常。
  2. internalSlotsList 为 « [[InitializedSegmenter]][[Locale]][[SegmenterGranularity]] »。
  3. segmenter 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.Segmenter.prototype%"internalSlotsList)。
  4. optionsResolution 为 ? ResolveOptions(%Intl.Segmenter%%Intl.Segmenter%.[[LocaleData]]localesoptions)。
  5. options 设为 optionsResolution.[[Options]]
  6. roptionsResolution.[[ResolvedLocale]]
  7. segmenter.[[Locale]] 设为 r.[[Locale]]
  8. granularity 为 ? GetOption(options"granularity"string,« "grapheme""word""sentence" »,"grapheme")。
  9. segmenter.[[SegmenterGranularity]] 设为 granularity
  10. 返回 segmenter

19.2 Intl.Segmenter 构造函数的属性

Intl.Segmenter 构造函数

19.2.1 Intl.Segmenter.prototype

Intl.Segmenter.prototype 的值为 %Intl.Segmenter.prototype%

此属性具有特性 { [[Writable]]false[[Enumerable]]false[[Configurable]]false }。

19.2.2 Intl.Segmenter.supportedLocalesOf ( locales [ , options ] )

当以参数 localesoptions 调用 supportedLocalesOf 方法时,执行如下步骤:

  1. availableLocales%Intl.Segmenter%.[[AvailableLocales]]
  2. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  3. 返回 ? FilterLocales(availableLocalesrequestedLocalesoptions)。

19.2.3 内部槽

[[AvailableLocales]] 内部槽的值为 实现自定义,受 9.1 的约束。

[[RelevantExtensionKeys]] 内部槽的值为 « »。

[[ResolutionOptionDescriptors]] 内部槽的值为 « »。

Intl.Segmenter 没有任何相关的扩展键。

[[LocaleData]] 内部槽的值为 实现自定义,受 9.1 的约束。

19.3 Intl.Segmenter 原型对象的属性

Intl.Segmenter 原型对象

  • %Intl.Segmenter.prototype%
  • 是一个普通对象
  • 不是 Intl.Segmenter 实例,也没有 [[InitializedSegmenter]] 内部槽或 Intl.Segmenter 实例对象的其他内部槽。
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%

19.3.1 Intl.Segmenter.prototype.constructor

Intl.Segmenter.prototype.constructor 的初始值为 %Intl.Segmenter%

19.3.2 Intl.Segmenter.prototype.resolvedOptions ( )

此函数用于访问对象初始化期间计算得到的语言环境和选项。

  1. segmenterthis 值。
  2. 执行 ? RequireInternalSlot(segmenter[[InitializedSegmenter]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. 按表序对 表 32 的每一行(除表头行)执行:
    1. p 为当前行的 Property 值。
    2. vsegmenter 的内部槽中名称为当前行 Internal Slot 的槽的值。
    3. 断言vundefined
    4. 执行 ! CreateDataPropertyOrThrow(optionspv)。
  5. 返回 options
表 32:Segmenter 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[SegmenterGranularity]] "granularity"

19.3.3 Intl.Segmenter.prototype.segment ( string )

在 Intl.Segmenter 实例上以参数 string 调用 Intl.Segmenter.prototype.segment 方法,以使用该 Intl.Segmenter 实例的语言环境和选项为该字符串创建一个Segments 实例。执行如下步骤:

  1. segmenterthis 值。
  2. 执行 ? RequireInternalSlot(segmenter[[InitializedSegmenter]])。
  3. string 为 ? ToString(string)。
  4. 返回 CreateSegmentsObject(segmenterstring)。

19.3.4 Intl.Segmenter.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Intl.Segmenter"

此属性具有特性 { [[Writable]]false[[Enumerable]]false[[Configurable]]true }。

19.4 Intl.Segmenter 实例的属性

Intl.Segmenter 实例是普通对象,继承自 %Intl.Segmenter.prototype% 的属性。

Intl.Segmenter 实例具有 [[InitializedSegmenter]] 内部槽。

Intl.Segmenter 实例还具有由 Intl.Segmenter 构造函数 计算得到的内部槽:

  • [[Locale]] 是字符串,其值为用于分段的语言环境的 language tag
  • [[SegmenterGranularity]] 是字符串值之一:"grapheme""word""sentence",用于标识要分段的文本元素类型。

19.5 Segments 对象

Segments 实例是一个对象,表示特定字符串的各个分段,且受其构造的 Intl.Segmenter 实例的语言环境和选项影响。

19.5.1 CreateSegmentsObject ( segmenterstring )

抽象操作 CreateSegmentsObject 接收参数 segmenter(一个 Intl.Segmenter)和 string(字符串),返回一个Segments 实例。该Segments 实例引用 segmenterstring。调用时执行如下步骤:

  1. internalSlotsList 为 « [[SegmentsSegmenter]][[SegmentsString]] »。
  2. segmentsOrdinaryObjectCreate(%IntlSegmentsPrototype%internalSlotsList)。
  3. segments.[[SegmentsSegmenter]] 设为 segmenter
  4. segments.[[SegmentsString]] 设为 string
  5. 返回 segments

19.5.2 %IntlSegmentsPrototype% 对象

%IntlSegmentsPrototype% 对象:

  • 是所有 Segments 对象的原型。
  • 是一个普通对象
  • 具有 [[Prototype]] 内部槽,其值为 %Object.prototype%
  • 具有以下属性:

19.5.2.1 %IntlSegmentsPrototype%.containing ( index )

在一个Segments 实例上以参数 index 调用 containing 方法,以返回一个Segment Data 对象,描述字符串中包含指定索引处码元的分段(依据该Segments 实例的构造 Intl.Segmenter 实例的语言环境和选项)。执行如下步骤:

  1. segmentsthis 值。
  2. 执行 ? RequireInternalSlot(segments[[SegmentsSegmenter]])。
  3. segmentersegments.[[SegmentsSegmenter]]
  4. stringsegments.[[SegmentsString]]
  5. lenstring 的长度。
  6. n 为 ? ToIntegerOrInfinity(index)。
  7. 如果 n < 0 或 nlen,返回 undefined
  8. startIndexFindBoundary(segmenterstringnbefore)。
  9. endIndexFindBoundary(segmenterstringnafter)。
  10. 返回 CreateSegmentDataObject(segmenterstringstartIndexendIndex)。

19.5.2.2 %IntlSegmentsPrototype% [ %Symbol.iterator% ] ( )

Segments 实例上调用 %Symbol.iterator% 方法,以基于其构造的 Intl.Segmenter 实例的语言环境和选项,在其字符串上创建一个Segment Iterator。执行如下步骤:

  1. segmentsthis 值。
  2. 执行 ? RequireInternalSlot(segments[[SegmentsSegmenter]])。
  3. segmentersegments.[[SegmentsSegmenter]]
  4. stringsegments.[[SegmentsString]]
  5. 返回 CreateSegmentIterator(segmenterstring)。

此函数的 "name" 属性的值为 "[Symbol.iterator]"

19.5.3 Segments 实例的属性

Segments 实例是普通对象,继承自 %IntlSegmentsPrototype%

Segments 实例具有引用其构造 Intl.Segmenter 实例的 [[SegmentsSegmenter]] 内部槽。

Segments 实例具有引用其公开分段的字符串值的 [[SegmentsString]] 内部槽。

19.6 Segment Iterator 对象

Segment Iterator 是一个对象,表示对特定字符串分段的一次特定迭代。

19.6.1 CreateSegmentIterator ( segmenterstring )

抽象操作 CreateSegmentIterator 接收参数 segmenter(一个 Intl.Segmenter)和 string(字符串),返回一个Segment Iterator。该Segment Iterator使用 segmenter 的语言环境和选项遍历 string。调用时执行如下步骤:

  1. internalSlotsList 为 « [[IteratingSegmenter]][[IteratedString]][[IteratedStringNextSegmentCodeUnitIndex]] »。
  2. iteratorOrdinaryObjectCreate(%IntlSegmentIteratorPrototype%internalSlotsList)。
  3. iterator.[[IteratingSegmenter]] 设为 segmenter
  4. iterator.[[IteratedString]] 设为 string
  5. iterator.[[IteratedStringNextSegmentCodeUnitIndex]] 设为 0。
  6. 返回 iterator

19.6.2 %IntlSegmentIteratorPrototype% 对象

%IntlSegmentIteratorPrototype% 对象:

19.6.2.1 %IntlSegmentIteratorPrototype%.next ( )

Segment Iterator实例上调用 next 方法,使其向前推进一个分段,并返回一个 IteratorResult 对象,描述新分段或声明迭代完成。执行如下步骤:

  1. iteratorthis 值。
  2. 执行 ? RequireInternalSlot(iterator[[IteratingSegmenter]])。
  3. segmenteriterator.[[IteratingSegmenter]]
  4. stringiterator.[[IteratedString]]
  5. startIndexiterator.[[IteratedStringNextSegmentCodeUnitIndex]]
  6. lenstring 的长度。
  7. 如果 startIndexlen,则
    1. 返回 CreateIteratorResultObject(undefinedtrue)。
  8. endIndexFindBoundary(segmenterstringstartIndexafter)。
  9. iterator.[[IteratedStringNextSegmentCodeUnitIndex]] 设为 endIndex
  10. segmentDataCreateSegmentDataObject(segmenterstringstartIndexendIndex)。
  11. 返回 CreateIteratorResultObject(segmentDatafalse)。

19.6.2.2 %IntlSegmentIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Segmenter String Iterator"

此属性具有特性 { [[Writable]]false[[Enumerable]]false[[Configurable]]true }。

19.6.3 Segment Iterator 实例的属性

Segment Iterator 实例是普通对象,从 %SegmentIteratorPrototype% 继承属性。 Segment Iterator 实例最初以 表 33 所述的内部槽创建。

表 33:Segment Iterator 实例的内部槽
内部槽 描述
[[IteratingSegmenter]] 用于迭代的 Intl.Segmenter 实例。
[[IteratedString]] 正在被迭代的字符串值。
[[IteratedStringNextSegmentCodeUnitIndex]] 在被迭代的字符串值中,下一个分段开始处的码元索引。

19.7 Segment Data 对象

Segment Data 对象是一个对象,表示来自字符串的一个特定分段。

19.7.1 CreateSegmentDataObject ( segmenterstringstartIndexendIndex )

抽象操作 CreateSegmentDataObject 接收参数 segmenter(一个 Intl.Segmenter)、string(字符串)、startIndex(非负整数)和 endIndex(非负整数),返回一个Segment Data 对象。该Segment Data 对象描述来自 segmenterstring 中由索引 startIndexendIndex 界定的分段。调用时执行如下步骤:

  1. lenstring 的长度。
  2. 断言endIndexlen
  3. 断言startIndex < endIndex
  4. resultOrdinaryObjectCreate(%Object.prototype%)。
  5. segmentsubstring(stringstartIndexendIndex) 的结果。
  6. 执行 ! CreateDataPropertyOrThrow(result"segment"segment)。
  7. 执行 ! CreateDataPropertyOrThrow(result"index"𝔽(startIndex))。
  8. 执行 ! CreateDataPropertyOrThrow(result"input"string)。
  9. granularitysegmenter.[[SegmenterGranularity]]
  10. 如果 granularity"word",则
    1. isWordLike 为一个布尔值,指示 string 中的 segment 是否在语言环境 segmenter.[[Locale]] 下被视为“类单词(word-like)”。
    2. 执行 ! CreateDataPropertyOrThrow(result"isWordLike"isWordLike)。
  11. 返回 result
某个分段是否为“类单词(word-like)”取决于实现,且建议实现使用对语言环境敏感的定制。通常,仅由空格和/或标点组成的分段(例如在 ICU(International Components for Unicode,文档见 https://unicode-org.github.io/icu-docs/)中以 "WORD_NONE" 边界结束的那些)不被视为“类单词”。

19.8 Segmenter 对象的抽象操作

19.8.1 FindBoundary ( segmenterstringstartIndexdirection )

抽象操作 FindBoundary 接收参数 segmenter(一个 Intl.Segmenter)、string(字符串)、startIndex(非负整数)和 directionbeforeafter),返回一个非负整数。它在 string 中,从索引 startIndex 处的码元按指定 direction 查找一个分段边界(依据 segmenter 的语言环境和选项),并返回紧随其后的码元索引。调用时执行如下步骤:

  1. lenstring 的长度。
  2. 断言startIndex < len
  3. localesegmenter.[[Locale]]
  4. granularitysegmenter.[[SegmenterGranularity]]
  5. 如果 directionbefore,则
    1. string 中查找一个分段边界:该边界前方至字符串起始最多有 startIndex 个码元;查找时使用语言环境 locale 和文本元素粒度 granularity
    2. 若找到边界,返回该边界之前在 string 中的码元数量。
    3. 返回 0。
  6. 断言directionafter
  7. string 中查找紧随索引 startIndex 处码元之后的第一个分段边界;查找时使用语言环境 locale 和文本元素粒度 granularity
  8. 若找到边界,返回该边界之前在 string 中的码元数量。
  9. 返回 len
边界判定取决于实现,但通用默认算法见 Unicode Standard Annex #29。建议实现使用对语言环境敏感的定制,例如 CLDR(Common Locale Data Repository,https://cldr.unicode.org)所提供的定制。

20 ECMAScript 语言规范中的与语言环境相关的函数

ECMA-262 描述了若干与语言环境相关的函数。实现本规范的 ECMAScript 实现应当按照此处的描述来实现这些函数。

本条款中的算法所创建的 Collator、NumberFormat 或 DateTimeFormat 对象仅在这些算法内部使用。它们从不被 ECMAScript 代码直接访问,且实现中不必实际存在这些对象。

20.1 String 原型对象的属性

20.1.1 String.prototype.localeCompare ( that [ , locales [ , options ] ] )

本定义取代 ECMA-26222.1.3.12 提供的定义。

当以参数 that 以及可选参数 localesoptions 调用 localeCompare 方法时,执行如下步骤:

  1. O 为 ? RequireObjectCoercible(this 值)。
  2. S 为 ? ToString(O)。
  3. thatValue 为 ? ToString(that)。
  4. collator 为 ? Construct(%Intl.Collator%, « locales, options »)。
  5. 返回 CompareStrings(collator, S, thatValue)。

此函数的 "length" 属性为 1𝔽

注 1
localeCompare 方法本身并不适合作为 Array.prototype.sort 的参数,因为后者需要一个带有两个参数的函数。
注 2
localeCompare 函数在设计上是通用的;它不要求其 this 值为 String 对象。因此,它可以被转移到其他类型的对象上作为方法使用。

20.1.2 String.prototype.toLocaleLowerCase ( [ locales ] )

本定义取代 ECMA-26222.1.3.26 提供的定义。

此函数将一个 String 值按 ECMA-2626.1.4 中的描述解释为一系列码点。执行如下步骤:

  1. O 为 ? RequireObjectCoercible(this 值)。
  2. S 为 ? ToString(O)。
  3. 返回 ? TransformCase(S, locales, lower)。
toLocaleLowerCase 函数在设计上是通用的;它不要求其 this 值为 String 对象。因此,它可以被转移到其他类型的对象上作为方法使用。

20.1.2.1 TransformCase ( S, locales, targetCase )

抽象操作 TransformCase 接收参数 S(字符串)、locales(一个ECMAScript 语言值)以及 targetCaselowerupper)。它按 ECMA-2626.1.4 中的描述,将 S 解释为一系列 UTF-16 编码的码点,并返回将其 ILD 转换为 targetCase 的结果(一个新的字符串值)。调用时执行如下步骤:

  1. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  2. 如果 requestedLocales 不是空的List,则
    1. requestedLocalerequestedLocales[0]。
  3. 否则,
    1. requestedLocaleDefaultLocale()。
  4. availableLocales 为一个可用语言环境列表,其中包含 Unicode 字符数据库具有与语言相关大小写映射的 语言标签。如果实现支持其他与语言环境相关的大小写映射,则 availableLocales 还应包含其对应的语言标签
  5. matchLookupMatchingLocaleByPrefix(availableLocales, « requestedLocale »)。
  6. matchundefined,令 localematch.[[locale]];否则令 locale"und"
  7. codePointsStringToCodePoints(S)。
  8. 如果 targetCaselower,则
    1. newCodePoints 为一个List,其元素为根据使用 locale 的实现派生算法或 Unicode 默认大小写转换算法,对 codePoints 进行小写转换后的结果。
  9. 否则,
    1. 断言targetCaseupper
    2. newCodePoints 为一个List,其元素为根据使用 locale 的实现派生算法或 Unicode 默认大小写转换算法,对 codePoints 进行大写转换后的结果。
  10. 返回 CodePointsToString(newCodePoints)。

码点映射可依据 Unicode 标准的默认大小写转换算法的定制版本而得。实现可以使用 Unicode 字符数据库中的 SpecialCasing.txt 文件和/或 CLDR 和/或任何其他自定义定制中定义的与语言环境相关的定制。无论如何定制,符合规范的实现的大小写转换算法在给定相同的输入码点、语言环境和目标大小写时必须始终产生相同的结果。

某些码点的大小写映射可能产生多个码点,因此结果长度可能与输入不同。由于 toLocaleUpperCasetoLocaleLowerCase 都具有与上下文相关的行为,这两个函数并不对称。换言之,s.toLocaleUpperCase().toLocaleLowerCase() 不一定等于 s.toLocaleLowerCase(),而 s.toLocaleLowerCase().toLocaleUpperCase() 也不一定等于 s.toLocaleUpperCase()

20.1.3 String.prototype.toLocaleUpperCase ( [ locales ] )

本定义取代 ECMA-26222.1.3.27 提供的定义。

此函数将一个 String 值按 ECMA-2626.1.4 中的描述解释为一系列码点。执行如下步骤:

  1. O 为 ? RequireObjectCoercible(this 值)。
  2. S 为 ? ToString(O)。
  3. 返回 ? TransformCase(S, locales, upper)。
toLocaleUpperCase 函数在设计上是通用的;它不要求其 this 值为 String 对象。因此,它可以被转移到其他类型的对象上作为方法使用。

20.2 Number 原型对象的属性

以下定义引用了在 ECMA-26221.1.3 中定义的抽象操作 thisNumberValue。

20.2.1 Number.prototype.toLocaleString ( [ locales [ , options ] ] )

本定义取代 ECMA-26221.1.3.4 提供的定义。

当以可选参数 localesoptions 调用 toLocaleString 方法时,执行如下步骤:

  1. x 为 ? ThisNumberValue(this 值)。
  2. numberFormat 为 ? Construct(%Intl.NumberFormat%, « locales, options »)。
  3. 返回 FormatNumeric(numberFormat, ! ToIntlMathematicalValue(x))。

20.3 BigInt 原型对象的属性

以下定义引用了在 ECMA-26221.2.3 中定义的抽象操作 thisBigIntValue。

20.3.1 BigInt.prototype.toLocaleString ( [ locales [ , options ] ] )

本定义取代 ECMA-26221.2.3.2 提供的定义。

当以可选参数 localesoptions 调用 toLocaleString 方法时,执行如下步骤:

  1. x 为 ? ThisBigIntValue(this 值)。
  2. numberFormat 为 ? Construct(%Intl.NumberFormat%, « locales, options »)。
  3. 返回 FormatNumeric(numberFormat, (x))。

20.4 Date 原型对象的属性

以下定义引用了在 ECMA-26221.4.4 中定义的抽象操作 thisTimeValue。

20.4.1 Date.prototype.toLocaleString ( [ locales [ , options ] ] )

本定义取代 ECMA-26221.4.4.39 提供的定义。

当以可选参数 localesoptions 调用 toLocaleString 方法时,执行如下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. xdateObject.[[DateValue]]
  4. 如果 xNaN,返回 "Invalid Date"
  5. dateFormat 为 ? CreateDateTimeFormat(%Intl.DateTimeFormat%, locales, options, any, all)。
  6. 返回 ! FormatDateTime(dateFormat, x)。

20.4.2 Date.prototype.toLocaleDateString ( [ locales [ , options ] ] )

本定义取代 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] ) 中提供的定义。

当以可选参数 localesoptions 调用 toLocaleDateString 方法时,执行如下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. xdateObject.[[DateValue]]
  4. 如果 xNaN,返回 "Invalid Date"
  5. dateFormat 为 ? CreateDateTimeFormat(%Intl.DateTimeFormat%, locales, options, date, date)。
  6. 返回 ! FormatDateTime(dateFormat, x)。

20.4.3 Date.prototype.toLocaleTimeString ( [ locales [ , options ] ] )

本定义取代 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] ) 中提供的定义。

当以可选参数 localesoptions 调用 toLocaleTimeString 方法时,执行如下步骤:

  1. dateObjectthis 值。
  2. 执行 ? RequireInternalSlot(dateObject, [[DateValue]])。
  3. xdateObject.[[DateValue]]
  4. 如果 xNaN,返回 "Invalid Date"
  5. timeFormat 为 ? CreateDateTimeFormat(%Intl.DateTimeFormat%, locales, options, time, time)。
  6. 返回 ! FormatDateTime(timeFormat, x)。

20.5 Array 原型对象的属性

20.5.1 Array.prototype.toLocaleString ( [ locales [ , options ] ] )

本定义取代 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) 中提供的定义。

当以可选参数 localesoptions 调用 toLocaleString 方法时,执行如下步骤:

  1. array 为 ? ToObject(this 值)。
  2. len 为 ? LengthOfArrayLike(array)。
  3. separator 为适用于 host environment 当前语言环境的、实现自定义的列表分隔符字符串值(例如 ", ")。
  4. R 为空字符串。
  5. k 为 0。
  6. k < len 时重复,
    1. k > 0,则
      1. R 设为 Rseparator字符串连接结果。
    2. nextElement 为 ? Get(array, ! ToString(𝔽(k)))。
    3. nextElementundefined 且非 null,则
      1. S 为 ? ToString(? Invoke(nextElement, "toLocaleString", « locales, options »))。
      2. R 设为 RS字符串连接结果。
    4. k 设为 k + 1。
  7. 返回 R
注 1
此算法的步骤与 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) 中的步骤相呼应,不同之处在于对 Invoke(nextElement, "toLocaleString") 现在传入了 localesoptions 作为参数。
注 2
数组的各个元素通过其 toLocaleString 方法被转换为字符串,然后这些字符串以实现自定义的、与语言环境相关的分隔符字符串分隔并连接。此函数与 toString 类似,但其目的是产生与 host environment 当前语言环境的惯例相符合的、与语言环境相关的结果。
注 3
toLocaleString 函数在设计上是通用的;它不要求其 this 值为 Array 对象。因此,它可以被转移到其他类型的对象上作为方法使用。

Annex A (informative) 与实现相关的行为

本规范的下列方面依赖于具体实现:

Annex B (informative) 引入与先前版本不兼容的增补与变更

Annex C (informative) 卷尾说明

本规范以纯文本源格式 EcmarkupGitHub 上编写。Ecmarkup 是一种 HTML 与 Markdown 的方言,为以纯文本撰写 ECMAScript 规范并将其处理为完整的 HTML 呈现提供了框架与工具集,该 HTML 呈现遵循本文件的编辑规范。Ecmarkup 基于并集成了多种格式与技术,包括用于定义语法的 Grammarkdown,以及用于撰写算法步骤的 Ecmarkdown。本规范的 PDF 版本通过将 HTML 呈现打印为 PDF 生成。

以往版本的本规范使用 Word 编写——本版所依赖的 Ecmarkup 源文本由将 ECMAScript 2015 的 Word 文档转换为 Ecmarkup 的自动化转换工具生成。

Copyright & Software License

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: https://ecma-international.org/

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.