Draft ECMA-402 / July 10, 2026

ECMAScript® 2027 Internationalization API Specification

贡献本规范

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

更多关于本文件创建方式的信息,请参见 colophon

介绍

本规范的源代码可在 https://github.com/tc39/ecma402 找到。

ECMAScript 2027 国际化 API 规范(ECMA-402 第14版)为 ECMA-262 提供了关键的语言敏感功能。其功能选自诸如 Unicode 国际化组件(ICU)库https://unicode-org.github.io/icu-docs/)、.NET 框架和 Java 平台等成熟的国际化 API。

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

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

第3版 API 是在 Ecma TC39 新的年度发布节奏和开放开发流程下发布的首个版本。ECMA-402 源文档被构建为纯文本源文件,作为后续完全在 GitHub 上开发的基础。在本标准开发的一年中,提交了数十个拉取请求和问题,涵盖了许多错误修复、编辑修正和其他改进。此外,还开发了许多软件工具以协助此工作,包括 Ecmarkup、Ecmarkdown 和 Grammarkdown。

许多组织的数十位个人在 Ecma TC39 内为本版及之前各版的开发做出了重要贡献。此外,一个充满活力的社区也在支持 TC39 的 ECMAScript 工作。该社区审查了众多草案,提交了数十份错误报告,进行了实现实验,贡献了测试套件,并向全球开发者社区普及了 ECMAScript 国际化。遗憾的是,无法识别和感谢每一位为此做出贡献的个人和组织。

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

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

Caridy Patiño
ECMA-402,第3、4、5版项目编辑

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

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

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

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

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

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

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

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

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

1 范围

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

2 一致性

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

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

符合性实现允许接受额外的值,并在以下 options 参数的属性中具有实现定义的行为,而不是抛出 RangeError

3 规范性引用

下列参考文献是本文件应用所必需的。对于有日期的引用,仅适用于所引用的版本。对于无日期的引用,适用参考文献的最新版本(包括任何修订)。

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

Note
本规范依赖于这些参考文献的部分会尽力保持更新,但不能保证与这些标准保持同步。

4 概述

本节为非规范性内容。

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

软件的国际化是指设计软件,使其支持或能够轻松适应不同语言和文化期望用户的需求,并实现全球范围内的交流。本地化则是实际针对特定语言和文化进行适配。软件全球化通常被理解为国际化和本地化的结合。全球化从最低层开始,采用支持所有语言的文本表示,并使用标准标识符来识别语言、国家、时区及其他相关参数。它还包括使用用户界面语言和用户理解的数据展示,最后通常需要针对用户的语言、文化和环境进行产品特定的适配。

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

4.2 API概述

本规范旨在补充ECMA-262,提供关键的语言敏感功能,可以整体或部分添加到其实现中。本规范引入了ECMAScript代码可观察的新语言值(如[[FallbackSymbol]]内部槽的值,以及通过属性访问%Intl%可递归访问的值集合),并细化了ECMA-262中某些函数的定义(如下所述)。这两类都不禁止ECMA-262中定义的值和接口允许的其他行为,以支持任何实现采用本规范。

本规范提供了大多数应用程序所需的几项关键语言敏感功能:区域选择与检查、字符串比较(排序)与大小写转换、复数规则、文本分段,以及数字、绝对和相对日期与时间、持续时间和列表的格式化。虽然ECMA-262为这些基本功能提供了函数(在Array.prototype上:toLocaleString;在String.prototype上:localeComparetoLocaleLowerCasetoLocaleUpperCase;在Number.prototype上:toLocaleString;在Date.prototype上:toLocaleStringtoLocaleDateStringtoLocaleTimeString),但它们的实际行为在很大程度上由实现决定。本规范提供了更多功能、对语言和行为细节的控制,以及更完整的功能规范。

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

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

Intl对象用于封装本规范定义的所有功能,以避免名称冲突。

Note
虽然API包含多种格式化器,但不提供任何解析功能。这是有意为之,经过充分讨论,并在权衡所有利弊后做出决定。详见问题追踪

4.3 API约定

每个Intl构造函数应表现得如同由类定义,在作为函数(无NewTarget)调用时抛出TypeError异常。为兼容以往版本,%Intl.Collator%%Intl.DateTimeFormat%%Intl.NumberFormat%在作为函数调用时仍会构造并返回新对象。

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

4.4 实现依赖

由于国际化的特殊性,本规范必须将若干细节留给实现决定:

  • 实现支持的具有充分本地化的区域集合:语言学家已描述了数千种人类语言,IANA语言子标签注册表包含7000多个主语言子标签(用于区域标识符)。即使是大型区域数据集,如Common Locale Data Repository,也只覆盖所有语言及其地区或方言变体的一小部分。针对资源受限设备的实现可能还需进一步缩减集合。
  • 本地化内容如格式模式的具体形式:许多情况下,区域相关的惯例并未标准化,因此可能存在多种形式,或随时间变化。不同国际化库可能实现了不同形式,但实际上都不算错误。为允许该API基于现有库实现,必须允许这些差异。
  • Unicode子集:某些操作(如排序)可作用于包含整个Unicode字符集的字符串。然而,Unicode标准和ECMAScript标准都允许实现将功能限制在Unicode字符集的子集。此外,区域惯例通常只规定与该区域相关字符的期望行为,而非整个Unicode字符集。Unicode排序算法结合了整个Unicode字符集的默认排序顺序和本地惯例的定制,子集和定制仍会导致行为差异。

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

在本规范中,实现和区域相关的行为称为ILD,实现、区域和编号系统相关的行为称为ILND

4.4.1 跨实现的兼容性

ECMA 402描述了其函数所用数据的结构。数据内容由实现决定,预期随时间变化且各实现不同。程序员可观察到这些差异,并可构造依赖特定输出的程序。但本规范力求描述合理约束,使编写良好的程序能在各实现间运行。鼓励实现继续努力协调语言数据。

5 符号约定

本标准使用 ECMA-262 的符号约定子集:

Note
ECMA-262 所述,算法用于精确指定 ECMAScript 构造的必要语义,但并不意味着必须采用任何特定的实现技术。内部槽用于定义对象值的语义,但不是 API 的一部分。它们仅用于说明目的。API 的实现必须表现得如同以此处描述的方式生成和操作内部槽。

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

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

5.1 知名内在对象

下表扩展了 Well-Known Intrinsic Objects 中定义的知名内在对象表。

Table 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 Locale、货币、时区、测量单位、编号系统、排序规则和日历的标识

本条描述本规范中用于标识 locale、货币、时区、测量单位、编号系统、排序规则、日历和 pattern 字符串的 String 值。

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

用于标识 locale、货币、文字和时区的 String 值以 ASCII 大小写不敏感的方式解释,将码元 0x0041 到 0x005A(对应 Unicode 字符 LATIN CAPITAL LETTER A 到 LATIN CAPITAL LETTER Z)视为等价于相应码元 0x0061 到 0x007A(对应 Unicode 字符 LATIN SMALL LETTER A 到 LATIN SMALL LETTER Z),两端均包含。不应用其他大小写折叠等价关系。

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

String 值 stringASCII-uppercase 是从 string 派生出的 String 值,其做法是将每个 ASCII 小写字母码元(0x0061 到 0x007A,含两端)替换为相应的 ASCII 大写字母码元(0x0041 到 0x005A,含两端),同时保留所有其他码元。

String 值 stringASCII-lowercase 是从 string 派生出的 String 值,其做法是将每个 ASCII 大写字母码元(0x0041 到 0x005A,含两端)替换为相应的 ASCII 小写字母码元(0x0061 到 0x007A,含两端),同时保留所有其他码元。

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

6.2 语言标签

本规范使用 Unicode BCP 47 locale 标识符来标识 locale,如 Unicode Technical Standard #35 Part 1 Core, Section 3.3 BCP 47 Conformance 所定义,并且其算法引用 Section 3 Unicode Language and Locale Identifiers 的语法中定义的 Unicode locale 非终结符。 每个这样的标识符也可称为一个 语言标签,并且事实上是 BCP 47 中使用该术语时的一个有效语言标签。 按照 Unicode Technical Standard #35 Part 1 Core, Section 3.2.1 Canonical Unicode Locale Identifiers 所规定的规范形式 locale 标识符称为“Unicode 规范化 locale 标识符”。

Locale 标识符由大小写不敏感的 Unicode Basic Latin 字母数字 子标签组成,这些子标签"-" (U+002D HYPHEN-MINUS) 字符分隔,单字符 子标签称为“singleton subtags”。 Unicode Technical Standard #35 Part 1 Core, Section 3.6 Unicode BCP 47 U Extension 子标签序列被广泛使用,而术语“Unicode locale 扩展序列”描述语言标签中最长的 substring,该 substring 可由 unicode_locale_extensions Unicode locale 非终结符匹配,并且不是 "-x-…" 私用 子标签序列的一部分。它以 "-u-" 开始,并包含所有紧随其后的非 singleton subtags 的 子标签,以及它们前面的 "-" 分隔符。例如,"en-US-u-fw-mon-x-u-ex-foobar"Unicode locale 扩展序列"-u-fw-mon"

所有格式良好的语言标签都适合与本规范定义的 API 一起使用,但实现不需要使用 Unicode Common Locale Data Repository(CLDR)数据来验证它们;实现以充分本地化支持的 locale 集合,以及由此支持的语言标签集合,是由实现定义的。Intl 构造函数将请求的语言标签映射到其各自实现支持的 locale。

6.2.1 IsWellFormedLanguageTag ( locale )

The abstract operation IsWellFormedLanguageTag takes argument locale (一个 String) and returns 一个 Boolean. 它确定 locale 是否为一个格式良好的语言标签,符合 unicode_bcp47_locale_id 的格式良好性约束。它不考虑 locale 是否传达任何有意义的语义,也不区分别名子标签及其首选替换子标签,或要求规范大小写或子标签顺序。 It performs the following steps when called:

  1. lowerLocalelocaleASCII-lowercase
  2. 如果 lowerLocale 不能由 unicode_locale_id Unicode locale 非终结符匹配,则返回 false
  3. 如果 lowerLocale 使用了 Unicode Technical Standard #35 Part 1 Core, Section 3.3 BCP 47 Conformance 中描述的任何向后兼容语法,则返回 false
  4. baseNameGetLocaleBaseName(lowerLocale)。
  5. variantsGetLocaleVariants(baseName)。
  6. 如果 variants 不是 undefined,则
    1. 如果 variants 包含任何重复子标签,则返回 false
  7. extensionslowerLocale 中跟在 baseName 之后的后缀。
  8. 注:由 pu_extensions Unicode locale 非终结符匹配的 "-x-…" 私用子标签序列必须被忽略,但没有后续内容的孤立最终 "x" 子标签不会影响以下任何检查。
  9. puIndexStringIndexOf(extensions, "-x-", 0)。
  10. 如果 puIndex 不是 not-found,则将 extensions 设置为 extensions 从 0 到 puIndex 的子字符串。
  11. 如果 extensions 不是空 String,则
    1. 如果 extensions 包含任何重复 singleton subtags,则返回 false
    2. transformExtensionextensions 中可由 transformed_extensions Unicode locale 非终结符匹配的最长 substring。如果没有这样的 substring,则返回 true
    3. 断言:transformExtension 从 0 到 3 的子字符串是 "-t-"
    4. tPrefixtransformExtension 从 3 开始的子字符串。
    5. tlangtPrefix 中可由 tlang Unicode locale 非终结符匹配的最长前缀。如果没有这样的前缀,则返回 true
    6. tlangVariantsGetLocaleVariants(tlang)。
    7. 如果 tlangVariants 不是 undefined,则
      1. 如果 tlangVariants 包含任何重复子标签,则返回 false
  12. 返回 true

6.2.2 CanonicalizeUnicodeLocaleId ( locale )

The abstract operation CanonicalizeUnicodeLocaleId takes argument locale (一个语言标签) and returns 一个 Unicode 规范化 locale 标识符. 它返回 locale 的规范且大小写规整化形式。 It performs the following steps when called:

  1. localeId 为执行 Processing LocaleIds 算法所得到的 String 值,以按照 Unicode Technical Standard #35 Part 1 Core, Annex C LocaleId Canonicalizationlocale 转换为规范形式。
  2. 如果 localeId 包含一个作为 Unicode locale 扩展序列substring,则
    1. extension 为由 localeIdUnicode locale 扩展序列substring 组成的 String 值。
    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]] 不是空 String,则
        1. newExtension 设置为 newExtension"-"keyword.[[Value]] 的字符串拼接。
    6. 断言:newExtension 不是 "-u"
    7. localeId 设置为 localeId 的副本,其中第一次出现的 substring extension 已被替换为 newExtension
  3. 返回 localeId
Note
步骤 2 确保返回的语言标签中的 Unicode locale 扩展序列包含:
  • 输入中任何重复属性的第一个实例,且仅包含该实例,以及
  • 输入中给定键的第一个 keyword,且仅包含该 keyword

6.2.3 DefaultLocale ( )

The implementation-defined abstract operation DefaultLocale takes no arguments and returns 一个 Unicode 规范化 locale 标识符. 返回的 String 值表示宿主环境当前 locale 的格式良好(6.2.1)且规范化(6.2.2)的语言标签。它不得包含 Unicode locale 扩展序列

Note
返回值是一个潜在的指纹识别向量。在浏览器环境中,它应与 navigator.language 匹配,以避免提供任何额外的可区分信息。

6.3 货币代码

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

允许所有格式良好的 3 字母 ISO 4217 货币代码。不过,可用本地化货币符号的货币代码和语言标签组合集合依赖于实现。当本地化货币符号不可用时,使用 ISO 4217 货币代码进行格式化。

6.3.1 IsWellFormedCurrencyCode ( currency )

The abstract operation IsWellFormedCurrencyCode takes argument currency (一个 String) and returns 一个 Boolean. 它验证 currency 实参是否表示一个格式良好的 3 字母 ISO 4217 货币代码。 It performs the following steps when called:

  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 ( )

The implementation-defined abstract operation AvailableCanonicalCurrencies takes no arguments and returns 一个 Strings 的 List. 返回的 List 按字典序码元顺序排序,并包含唯一、格式良好且大写规范化的 3 字母 ISO 4217 货币代码,标识实现为 Intl.DisplayNames 和 Intl.NumberFormat 对象提供功能的货币。

6.5 IANA Time Zone Database 的使用

采用本规范的实现必须感知时区:它们必须使用 IANA Time Zone Database https://www.iana.org/time-zones/ 来提供可用的命名时区标识符,以及在 ECMAScript 计算和格式化中使用的数据。 本节定义时区感知实现应如何使用 IANA Time Zone Database。 除非某个 String 是 IANA Time Zone Database 中的 Zone 名称或 Link 名称,否则它不得是可用的命名时区标识符。 ECMAScript 内置对象返回的可用命名时区标识符必须使用 IANA Time Zone Database 中的大小写形式。

IANA Time Zone Database 中的每个 Zone 都必须是一个主时区标识符,IANA Time Zone Database 中的每个 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"
Note

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

Unicode Common Locale Data Repository(CLDR)在确定哪些可用命名时区标识符是主或非主标识符时,实现了上述大部分例外。 尽管建议使用 CLDR 数据以保持实现之间的一致性,但并非必需。 非基于 CLDR 的实现仍可使用 CLDR 在 timezone.xml 中的标识符数据。 实现也可以直接构建 IANA Time Zone Database,例如使用 PACKRATDATA=backzone PACKRATLIST=zone.tab 等构建选项,并执行任何所需的后处理,以确保符合上述要求。

IANA Time Zone Database 通常每年更新五到十次。 这些更新可能会添加新的 Zone 或 Link 名称,可能会将 Zone 改为 Link,并可能会更改与任何 Zone 关联的 UTC 偏移和转换。 建议实现尽快包含 IANA Time Zone Database 的更新。 此类及时行动可确保 ECMAScript 程序能够准确执行时区敏感计算,并能够使用由外部输入或宿主环境提供的新添加的可用命名时区标识符。

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

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

等待期只应在添加新的 Zone 以替换现有 Zone 时适用。 如果现有 Zone 和 Link 被交换,则未发生重命名,也不需要等待期。

如果实现会在某个 agent 的生命周期内修订时区信息,则要求可用命名时区标识符列表、与任何可用命名时区标识符关联的主时区标识符,以及与任何可用命名时区标识符关联的 UTC 偏移和转换,都与该 agent 先前观察到的结果一致。 由于支持此要求的复杂性,建议实现为每个 agent 的生命周期维护 IANA Time Zone Database 的完全一致副本。

本节补充但不取代 21.4.1.19

6.5.1 AvailableNamedTimeZoneIdentifiers ( )

The implementation-defined abstract operation AvailableNamedTimeZoneIdentifiers takes no arguments and returns 一个 Time Zone Identifier RecordsList. 其结果描述此实现中的所有可用命名时区标识符,以及与每个可用命名时区标识符对应的主时区标识符。 该 List 按每个 Time Zone Identifier Record[[Identifier]] 字段排序。

此定义取代 21.4.1.23 中提供的定义。

  1. identifiers 为一个 List,包含 IANA Time Zone Database 中每个 Zone 或 Link 名称的 String 值。
  2. 断言:identifiers 中没有任何元素与任何其他元素形成 ASCII-case-insensitive match
  3. 按字典序码元顺序排序 identifiers
  4. result 为一个新的空 List
  5. identifiers 的每个元素 identifier,执行
    1. primaryidentifier
    2. 如果 identifier 是 IANA Time Zone Database 中的 Link 名称,且 identifier 未出现在 IANA Time Zone Database 的 zone.tab 的 “TZ” 列中,则
      1. zoneidentifier 根据 IANA Time Zone Database 中解析 Link 名称规则解析到的 Zone 名称。
      2. 如果 zone"Etc/" 开头,则
        1. primary 设置为 zone
      3. 否则,
        1. identifierCountryCode 为其领土包含 identifier 所对应地理区域的 ISO 3166-1 Alpha-2 国家代码。
        2. zoneCountryCode 为其领土包含 zone 所对应地理区域的 ISO 3166-1 Alpha-2 国家代码。
        3. 如果 identifierCountryCodezoneCountryCode,则
          1. primary 设置为 zone
        4. 否则,
          1. countryCodeLineCount 为 IANA Time Zone Database 的文件 zone.tab 中 “country-code” 列为 identifierCountryCode 的行数。
          2. 如果 countryCodeLineCount 是 1,则
            1. countryCodeLine 为 IANA Time Zone Database 的文件 zone.tab 中 “country-code” 列为 identifierCountryCode 的那一行。
            2. primary 设置为 countryCodeLine 的 “TZ” 列内容。
          3. 否则,
            1. backzoneundefined
            2. backzoneLinkLines 为 IANA Time Zone Database 的文件 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 utcRecord,使得 utcRecord.[[Identifier]]"UTC"utcRecord.[[PrimaryIdentifier]]"UTC"
  7. 返回 result
Note 1

上述将 Links 解析为主时区标识符的算法旨在对应 International Components for Unicode(ICU)中 icu::TimeZone::getIanaID() 的行为,以及 Unicode Common Locale Data Repository(CLDR)中维护时区标识符数据的流程。

此算法使用 IANA Time Zone Database 的文件 zone.tabbackzone 中的数据,将 Links 解析为主时区标识符,同时不跨越 ISO 3166-1 Alpha-2 国家代码的边界。 如果某个 Link 的国家代码在 zone.tab 中只有一行,则该行将决定主时区标识符。 但是,如果该国家代码在 zone.tab 中有多行,则必须使用 backzone 中的历史映射来确定正确的主时区标识符。

例如,如果 IANA Time Zone Database 的默认构建选项将 "Pacific/Truk"(国家代码 "FM")标识为指向 "Pacific/Port_Moresby"(国家代码 "PG")的 Link,则要解析 "Pacific/Truk",必须检查 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 Time Zone Database 的 2024a 版本,"Atlantic/Jan_Mayen" 是唯一发生这种情况的案例。

Note 2
IANA Time Zone Database 中的时区标识符会随时间变化。 至少,建议实现在 surrounding agent 的生命周期内,将 AvailableNamedTimeZoneIdentifiers 结果的更改限制为 GetAvailableNamedTimeZoneIdentifier 允许的更改。 由于支持这些建议的复杂性,建议 AvailableNamedTimeZoneIdentifiers 的结果在 surrounding agent 的生命周期内保持不变。

6.5.2 GetAvailableNamedTimeZoneIdentifier ( timeZoneIdentifier )

The abstract operation GetAvailableNamedTimeZoneIdentifier takes argument timeZoneIdentifier (一个 String) and returns 要么是一个 Time Zone Identifier Record,要么是 empty. 如果 timeZoneIdentifier 是一个可用命名时区标识符,则它返回 AvailableNamedTimeZoneIdentifiers 返回的 List 中的一个 Record。 否则,将返回 empty。 It performs the following steps when called:

  1. AvailableNamedTimeZoneIdentifiers() 的每个元素 record,执行
    1. 如果 record.[[Identifier]]timeZoneIdentifier 形成 ASCII-case-insensitive match,则返回 record
  2. 返回 empty
Note
对任何 timeZoneIdentifier,或任何与其形成 ASCII-case-insensitive match 的值,都要求得到的 Time Zone Identifier Recordsurrounding agent 的生命周期内包含相同的字段值。 此外,要求时区标识符在 surrounding agent 的生命周期内不得动态地从主变为非主,这意味着如果 timeZoneIdentifier 与先前调用 GetAvailableNamedTimeZoneIdentifier 的结果的 [[PrimaryIdentifier]] 字段形成 ASCII-case-insensitive match,则 GetAvailableNamedTimeZoneIdentifier(timeZoneIdentifier) 必须返回一个 Time Zone Identifier Record,其中 [[Identifier]][[PrimaryIdentifier]]。 由于支持这些要求的复杂性,建议 AvailableNamedTimeZoneIdentifiers 的结果(因此也包括 GetAvailableNamedTimeZoneIdentifier)在 surrounding agent 的生命周期内保持不变。

6.5.3 AvailablePrimaryTimeZoneIdentifiers ( )

The abstract operation AvailablePrimaryTimeZoneIdentifiers takes no arguments and returns 一个 Strings 的 List. 返回的 List 是 IANA Time Zone Database 中受支持的 Zone 和 Link 名称的已排序 List。 It performs the following steps when called:

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

6.5.4 StringSplitToList ( string, separator )

The abstract operation StringSplitToList takes arguments string (一个 String) and separator (一个 String) and returns 一个 Strings 的 List. 返回的 List 包含 string 中所有互不相交的 substring,这些 substring 不包含 separator,但其前面紧邻和/或后面紧邻一次 separator 出现。 每个这样的 substring 可以是相邻 separator 出现之间的空 String,可以是在 string 最开始处的 separator 之前,也可以是在 string 最末尾处的 separator 之后;除此之外不会为空。 It performs the following steps when called:

  1. 断言:string 不是空 String。
  2. 断言:separator 不是空 String。
  3. separatorLengthseparator 的长度。
  4. substrings 为一个新的空 List
  5. i 为 0。
  6. jStringIndexOf(string, separator, 0)。
  7. 重复,当 j 不是 not-found 时,
    1. substringstringij 的子字符串。
    2. substring 追加到 substrings
    3. i 设置为 j + separatorLength
    4. j 设置为 StringIndexOf(string, separator, i)。
  8. substringstringi 开始的子字符串。
  9. substring 追加到 substrings
  10. 返回 substrings

6.6 测量单位标识符

本规范使用 core unit identifier(或等价地称为 core unit ID)来标识测量单位,如 Unicode Technical Standard #35 Part 2 General, Section 6.2 Unit Identifiers 所定义。它们的规范形式是一个仅包含 Unicode Basic Latin 小写字母(U+0061 LATIN SMALL LETTER A 到 U+007A LATIN SMALL LETTER Z)并带有零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

只有有限集合的 core unit identifiers 得到许可。 尝试使用未经许可的 core unit identifier 会导致 RangeError

6.6.1 IsWellFormedUnitIdentifier ( unitIdentifier )

The abstract operation IsWellFormedUnitIdentifier takes argument unitIdentifier (一个 String) and returns 一个 Boolean. 它验证 unitIdentifier 实参是否表示一个格式良好的 core unit identifier,该标识符要么是一个受许可的单一单位,要么是由两个受许可单一单位相除形成的复合单位。 It performs the following steps when called:

  1. 如果 IsSanctionedSingleUnitIdentifier(unitIdentifier) 是 true,则
    1. 返回 true
  2. numeratorAndDenominatorStringSplitToList(unitIdentifier, "-per-")。
  3. 如果 numeratorAndDenominator 不恰好有 2 个元素,则返回 false
  4. 如果 IsSanctionedSingleUnitIdentifier(numeratorAndDenominator[0]) 是 false,则返回 false
  5. 如果 IsSanctionedSingleUnitIdentifier(numeratorAndDenominator[1]) 是 false,则返回 false
  6. 返回 true

6.6.2 IsSanctionedSingleUnitIdentifier ( unitIdentifier )

The abstract operation IsSanctionedSingleUnitIdentifier takes argument unitIdentifier (一个 String) and returns 一个 Boolean. 它验证 unitIdentifier 实参是否属于本规范当前版本中许可的单一单位标识符,这些标识符是 Common Locale Data Repository release 38 unit validity data 的一个子集;该列表可能随时间增长。如 Unicode Technical Standard #35 Part 2 General, Section 6.2 Unit Identifiers 中所讨论,单一单位标识符是不由其他单位标识符相乘或相除组成的 core unit identifier。 It performs the following steps when called:

  1. 如果 unitIdentifier 列在下面的 Table 2 中,则返回 true
  2. 否则,返回 false
Table 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 ( )

The abstract operation AvailableCanonicalUnits takes no arguments and returns 一个 Strings 的 List. 返回的 List 按字典序码元顺序排序,并由 Table 2 的每一行(表头行除外)中列出的 simple unit identifiers 的唯一值组成。

6.7 编号系统标识符

本规范使用 编号系统标识符来标识编号系统,该标识符对应于 Unicode Technical Standard #35 Part 3 Numbers, Section 1 Numbering Systems 所引用的名称。它们的规范形式是仅包含 Unicode Basic Latin 小写字母(U+0061 LATIN SMALL LETTER A 到 U+007A LATIN SMALL LETTER Z)的字符串。

6.7.1 AvailableCanonicalNumberingSystems ( )

The implementation-defined abstract operation AvailableCanonicalNumberingSystems takes no arguments and returns 一个 Strings 的 List. 返回的 List 按字典序码元顺序排序,并包含唯一的规范编号系统标识符,标识实现为 Intl.DateTimeFormat、Intl.NumberFormat 和 Intl.RelativeTimeFormat 对象提供功能的编号系统。该 List 必须包含 Table 30 的每一行(表头行除外)的 Numbering System 值。

6.8 排序规则类型

本规范使用 排序规则类型来标识排序规则,如 Unicode Technical Standard #35 Part 5 Collation, Section 3.1 Collation Types 所定义。它们的规范形式是一个仅包含 Unicode Basic Latin 小写字母(U+0061 LATIN SMALL LETTER A 到 U+007A LATIN SMALL LETTER Z)并带有零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

6.8.1 AvailableCanonicalCollations ( )

The implementation-defined abstract operation AvailableCanonicalCollations takes no arguments and returns 一个 Strings 的 List. 返回的 List 按字典序码元顺序排序,并包含唯一的规范排序规则类型,标识实现为 Intl.Collator 对象提供功能的排序规则。

6.9 日历类型

本规范使用 日历类型来标识日历,如 Unicode Technical Standard #35 Part 4 Dates, Section 2 Calendar Elements 所定义。它们的规范形式是一个仅包含 Unicode Basic Latin 小写字母(U+0061 LATIN SMALL LETTER A 到 U+007A LATIN SMALL LETTER Z)并带有零个或多个中间连字符(U+002D HYPHEN-MINUS)的字符串。

6.9.1 AvailableCalendars ( )

The implementation-defined abstract operation AvailableCalendars takes no arguments and returns 一个 Strings 的 List. 返回的 List 按字典序码元顺序排序,并包含规范形式(6.9)的唯一日历类型,标识实现为 Intl.DateTimeFormat 对象提供功能的日历,包括其别名(例如,要么同时包含 "islamicc""islamic-civil",要么两者都不包含)。该 List 必须包含 "iso8601"

6.10 Pattern String 类型

Pattern String 是一个 String 值,它包含零个或多个形式为 "{key}" 的子字符串,其中 key 可以是仅由 ASCII word characters 中的元素组成的任何非空序列。抽象 pattern 字符串的语法是实现细节,不会暴露给 ECMA-402 的用户。

7 ECMAScript标准内置对象的要求

除非本文件另有规定,本标准中描述的对象、函数和构造器,均需遵守ECMAScript Standard Built-in Objects中规定的标准内置ECMAScript对象的通用要求和限制。

8 Intl 对象

Intl 对象

8.1 Intl 对象的值属性

8.1.1 Intl [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是 String 值 "Intl"

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

8.2 Intl 对象的构造函数属性

除 Intl.Locale 外,以下每个构造函数都是一个服务构造函数,用于创建提供 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 )

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

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

8.3.2 Intl.supportedValuesOf ( key )

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

  1. key 设为 ? ToString(key)。
  2. 如果 key"calendar",则
    1. list 为一个新的空 List
    2. AvailableCalendars() 的每个元素 identifier,执行
      1. canonicalCanonicalizeUValue("ca", identifier)。
      2. 如果 identifiercanonical,则
        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 Locale 和参数协商

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

Available Locales List 是一个任意排序、无重复的语言标签 List,其中每个语言标签都是格式良好的规范化的,并且缺少 Unicode locale 扩展序列。它表示实现会在特定上下文中为其提供功能的所有 locale。

Language Priority List 是一个由格式良好规范化语言标签组成的 List,表示按优先级降序排列的 locale 偏好序列。它对应于 BCP 47RFC 4647 section 2.3 中定义的同名术语,但禁止 "*" 元素,并且只包含规范化内容。

Resolution Option Descriptor 是一个 Record,带有字段 [[Key]](一个字符串,通常是 [[RelevantExtensionKeys]] List 的一个元素)和 [[Property]](一个字符串),并且可选地还带有 [[Type]]booleanstring)和 [[Values]]empty 或 ECMAScript 语言值的 List)二者之一或二者。它描述在对象构造期间如何读取与 locale 解析相关的选项。

9.1 服务构造函数的内部槽

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

Note
例如,DateTimeFormat 的实现可能会在其 [[AvailableLocales]] 内部槽中包含语言标签 "fa-IR",并且必须(根据 11.2.3)在其 [[RelevantExtensionKeys]] 内部槽中包含键 "ca""hc""nu"。 该 locale 的默认日历通常是 "persian",但实现也可能支持 "gregory""islamic""islamic-civil"。 因此,DateTimeFormat [[LocaleData]] 内部槽中的 Record 会包含一个 [[fa-IR]] 字段,其值类似于 { [[ca]]: « "persian", "gregory", "islamic", "islamic-civil" », [[hc]]: « … », [[nu]]: « … » },以及其他具有相同值形状但其 List 中元素不同的 locale 命名字段。

9.2 抽象操作

9.2.1 CanonicalizeLocaleList ( locales )

The abstract operation CanonicalizeLocaleList takes argument locales (一个 ECMAScript 语言值) and returns 要么是包含一个 Language Priority List 的正常完成,要么是一个抛出完成. It performs the following steps when called:

  1. 如果 localesundefined,则
    1. 返回一个新的空 List
  2. seen 为一个新的空 List
  3. 如果 locales 是一个 String,或者 locales 是一个 Object 且 locales 具有 [[InitializedLocale]] 内部槽,则
    1. localesObjCreateArrayFromListlocales »)。
  4. 否则,
    1. localesObj 为 ? ToObject(locales)。
  5. length 为 ? LengthOfArrayLike(localesObj)。
  6. k 为 0。
  7. 重复,当 k < length 时,
    1. propertyKey 为 ! ToString(𝔽(k))。
    2. exists 为 ? HasProperty(localesObj, propertyKey)。
    3. 如果 existstrue,则
      1. element 为 ? Get(localesObj, propertyKey)。
      2. 如果 element 既不是 String 也不是 Object,则抛出一个 TypeError 异常。
      3. 如果 element 是 Object 且 element 具有 [[InitializedLocale]] 内部槽,则
        1. tagelement.[[Locale]]
      4. 否则,
        1. tag 为 ? ToString(element)。
      5. 如果 IsWellFormedLanguageTag(tag) 是 false,则抛出一个 RangeError 异常。
      6. canonicalizedTagCanonicalizeUnicodeLocaleId(tag)。
      7. 如果 seen 不包含 canonicalizedTag,则将 canonicalizedTag 追加到 seen
    4. k 设置为 k + 1。
  8. 返回 seen
Note 1
非规范性摘要:此抽象操作将 locales 实参解释为数组,并将其元素复制到一个 List 中,将这些元素验证为格式良好的语言标签并进行规范化,同时省略重复项。
Note 2
要求 element 为 String 或 Object,意味着 Number 值 NaN 不会被解释为语言标签 "nan",后者表示闽南语。

9.2.2 CanonicalizeUValue ( ukey, uvalue )

The abstract operation CanonicalizeUValue takes arguments ukey (定义于 Unicode Technical Standard #35 Part 1 Core Section 3.6.1 Key and Type DefinitionsUnicode locale 扩展序列键) and uvalue (一个 String) and returns 一个 String. 返回的 String 是 uvalue 作为 ukey 的值时的规范且大小写规整化形式。 It performs the following steps when called:

  1. lowerValueuvalueASCII-lowercase
  2. canonicalized 为将 lowerValue 作为键 ukey 的值并按照 Unicode Technical Standard #35 Part 1 Core, Annex C LocaleId Canonicalization Section 5 Canonicalizing Syntax, Processing LocaleIds 进行规范化后得到的 String 值。
  3. 注:建议实现使用 Common Locale Data Repository 提供的 common/bcp47 中的 'u' 扩展数据(可在 https://cldr.unicode.org/ 获取)。
  4. 返回 canonicalized

9.2.3 LookupMatchingLocaleByPrefix ( availableLocales, requestedLocales )

The abstract operation LookupMatchingLocaleByPrefix takes arguments availableLocales (一个 Available Locales List) and requestedLocales (一个 Language Priority List) and returns 一个带有字段 [[locale]](一个 Unicode 规范化 locale 标识符)和 [[extension]](一个 Unicode locale 扩展序列empty)的 Record,或 undefined. 它使用 BCP 47RFC 4647 section 3.4 中定义的 lookup 算法,在忽略 Unicode locale 扩展序列的情况下,确定 availableLocales 中满足 requestedLocales 的最佳元素。如果找到非默认匹配,则返回一个 Record,该 Record 带有 [[locale]] 字段,其中包含来自 availableLocales 的匹配语言标签;还带有 [[extension]] 字段,其中包含 requestedLocales 对应元素的 Unicode locale 扩展序列(如果请求的语言标签没有这样的序列,则为 empty)。 It performs the following steps when called:

  1. requestedLocales 的每个元素 locale,执行
    1. extensionempty
    2. 如果 locale 包含一个 Unicode locale 扩展序列,则
      1. extension 设置为 localeUnicode locale 扩展序列
      2. locale 设置为移除任何 Unicode locale 扩展序列后的 locale 的 String 值。
    3. prefixlocale
    4. 重复,当 prefix 不是空 String 时,
      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
Note
当请求的 locale 包含 Unicode Technical Standard #35 Part 1 Core BCP 47 T Extension 子标签序列时,此算法中的截断可能会临时生成无效语言标签。不过,它们都不会被返回,因为 availableLocales 只包含有效语言标签

9.2.4 LookupMatchingLocaleByBestFit ( availableLocales, requestedLocales )

The implementation-defined abstract operation LookupMatchingLocaleByBestFit takes arguments availableLocales (一个 Available Locales List) and requestedLocales (一个 Language Priority List) and returns 一个带有字段 [[locale]](一个 Unicode 规范化 locale 标识符)和 [[extension]](一个 Unicode locale 扩展序列empty)的 Record,或 undefined. 它在忽略 Unicode locale 扩展序列的情况下,确定 availableLocales 中满足 requestedLocales 的最佳元素。该算法依赖于实现,但其产生的结果应至少与 LookupMatchingLocaleByPrefix 算法产生的结果一样好,这是请求 locale 的典型用户会认为的标准。如果找到非默认匹配,则返回一个 Record,该 Record 带有 [[locale]] 字段,其中包含来自 availableLocales 的匹配语言标签;还带有 [[extension]] 字段,其中包含 requestedLocales 对应元素的 Unicode locale 扩展序列(如果请求的语言标签没有这样的序列,则为 empty)。

9.2.5 UnicodeExtensionComponents ( extension )

The abstract operation UnicodeExtensionComponents takes argument extension (一个 Unicode locale 扩展序列) and returns 一个带有字段 [[Attributes]][[Keywords]]Record. 它将 extension 拆解为一个唯一 attributes 的 List 和一个键唯一的 keywordsList。属性或 keyword 键在第一次之后的任何重复出现都会被忽略。 It performs the following steps when called:

  1. 断言:extension 的 ASCII 小写形式是 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,令 lengthsize - k;否则令 lengthe - k
    3. subtagextensionkk + length 的子字符串。
    4. 注:关键字是一个子标签序列,其中第一个是长度为 2 的键,任何后续子标签(如果存在)的长度都在 3 到 8 的闭区间内,它们连同其中间的 "-" 分隔符共同构成一个值。属性是一个长度在 3 到 8 的闭区间内、且位于所有关键字之前的单个子标签
    5. 断言:length ≥ 2。
    6. 如果 keywordundefinedlength ≠ 2,则
      1. 如果 subtag 不是 attributes 的元素,则将 subtag 追加到 attributes
    7. 否则如果 length = 2,则
      1. keyword 设为 Record { [[Key]]: subtag, [[Value]]: 空 String }。
      2. 如果 keywords 不包含其 [[Key]]keyword.[[Key]] 的元素,则将 keyword 追加到 keywords
    8. 否则如果 keyword.[[Value]] 是空 String,则
      1. keyword.[[Value]] 设为 subtag
    9. 否则,
      1. keyword.[[Value]] 设为 keyword.[[Value]]"-"subtag 的字符串连接。
    10. k 设为 k + length + 1。
  9. 返回 Record { [[Attributes]]: attributes, [[Keywords]]: keywords }。

9.2.6 InsertUnicodeExtensionAndCanonicalize ( locale, attributes, keywords )

The abstract operation InsertUnicodeExtensionAndCanonicalize takes arguments locale (一个语言标签), attributes (一个 Strings 的 List), and keywords (一个 RecordsList) and returns 一个 Unicode 规范化 locale 标识符. 它将 attributeskeywords 作为 Unicode locale 扩展序列并入 locale,并返回规范化后的结果。 It performs the following steps when called:

  1. 断言:locale 不包含 Unicode locale 扩展序列
  2. extension"-u"
  3. attributes 的每个元素 attr,执行
    1. extension 设置为 extension"-"attr 的字符串拼接。
  4. keywords 的每个 Record { [[Key]], [[Value]] } keyword,执行
    1. extension 设置为 extension"-"keyword.[[Key]] 的字符串拼接。
    2. 如果 keyword.[[Value]] 不是空 String,则将 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. 断言:IsWellFormedLanguageTag(newLocale) 是 true
  10. 返回 CanonicalizeUnicodeLocaleId(newLocale)。

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

The abstract operation ResolveLocale takes arguments availableLocales (一个 Available Locales List), requestedLocales (一个 Language Priority List), options (一个 Record), relevantExtensionKeys (一个 Strings 的 List), and localeData (一个 Record) and returns 一个 Record. 它执行 BCP 47RFC 4647 section 3 中定义的 "lookup",根据 options.[[localeMatcher]] 所指定的 LookupMatchingLocaleByBestFit 算法或 LookupMatchingLocaleByPrefix 算法,在忽略 Unicode locale 扩展序列的情况下,确定 availableLocales 中满足 requestedLocales 的最佳元素,并返回该匹配的表示,其中还包含来自 localeData 的对应数据,以及 relevantExtensionKeys 的每个元素的已解析值(默认为来自匹配 locale 的数据,如果存在请求的 Unicode locale 扩展序列,则由其数据覆盖,随后如果 options 中存在则由 options 的数据覆盖)。如果 requestedLocales 中匹配的元素包含 Unicode locale 扩展序列,则该序列会被复制到返回的 Record[[Locale]] 字段中的语言标签上,但会省略其 key 值不包含在 relevantExtensionKeys 中,或其 type 值被来自 options 的不同值取代的任何 keyword Unicode locale 非终结符。 It performs the following steps when called:

  1. matcheroptions.[[localeMatcher]]
  2. 如果 matcher"lookup",则
    1. matchLookupMatchingLocaleByPrefix(availableLocales, requestedLocales)。
  3. 否则,
    1. matchLookupMatchingLocaleByBestFit(availableLocales, requestedLocales)。
  4. 如果 matchundefined,将 match 设为 Record { [[locale]]: DefaultLocale(), [[extension]]: empty }。
  5. foundLocalematch.[[locale]]
  6. foundLocaleDatalocaleData.[[<foundLocale>]]。
  7. 断言:foundLocaleData 是一个 Record
  8. result 为一个新的 Record
  9. result.[[LocaleData]] 设为 foundLocaleData
  10. 如果 match.[[extension]] 不是 empty,则
    1. componentsUnicodeExtensionComponents(match.[[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 是一个 String 或 valuenull
    5. supportedKeywordempty
    6. 如果 keywords 包含一个其 [[Key]]key 的元素,则
      1. entrykeywords 中其 [[Key]]key 的元素。
      2. requestedValueentry.[[Value]]
      3. 如果 requestedValue 不是空 String,则
        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]]: 空 String }。
    7. 断言:options 具有字段 [[<key>]]。
    8. optionsValueoptions.[[<key>]]。
    9. 断言:optionsValue 是一个 String,或 optionsValueundefinednull
    10. 如果 optionsValue 是一个 String,则
      1. ukeykey 的 ASCII 小写形式。
      2. optionsValue 设为 CanonicalizeUValue(ukey, optionsValue)。
      3. 如果 optionsValue 是空 String,则
        1. optionsValue 设为 "true"
    11. 如果 SameValue(optionsValue, value) 是 falsekeyLocaleData 包含 optionsValue,则
      1. value 设为 optionsValue
      2. supportedKeyword 设为 empty
    12. 如果 supportedKeyword 不是 empty,则将 supportedKeyword 追加到 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 ( ctor, localeData, locales, options [ , specialBehaviours [ , modifyResolutionOptions ] ] )

The abstract operation ResolveOptions takes arguments ctor (一个服务构造函数), localeData (一个 Record), locales (一个 ECMAScript 语言值), and options (一个 ECMAScript 语言值) and optional arguments specialBehaviours (一个 enumsList) and modifyResolutionOptions (一个带有一个参数的 Abstract Closure) and returns 要么是包含一个带有字段 [[Options]](一个 Object)、[[ResolvedLocale]](一个 Record)和 [[ResolutionOptions]](一个 Record)的 Record 的正常完成,要么是一个抛出完成. 它读取 ctor 的输入并将它们解析为一个 locale。 It performs the following steps when called:

  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. ctor.[[ResolutionOptionDescriptors]] 的每个 Resolution Option Descriptor desc,执行
    1. 如果 desc 具有 [[Type]] 字段,则令 typedesc.[[Type]]。否则,令 typestring
    2. 如果 desc 具有 [[Values]] 字段,则令 valuesdesc.[[Values]]。否则,令 valuesempty
    3. value 为 ? GetOption(options, desc.[[Property]], type, values, undefined)。
    4. 如果 value 不是 undefined,则
      1. value 设置为 ! ToString(value)。
      2. 如果 value 不能由 type Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    5. keydesc.[[Key]]
    6. opt.[[<key>]] 设置为 value
  7. 如果 modifyResolutionOptions 存在,则执行 ! modifyResolutionOptions(opt)。
  8. resolutionResolveLocale(ctor.[[AvailableLocales]], requestedLocales, opt, ctor.[[RelevantExtensionKeys]], localeData)。
  9. 返回 Record { [[Options]]: options, [[ResolvedLocale]]: resolution, [[ResolutionOptions]]: opt }。

9.2.9 FilterLocales ( availableLocales, requestedLocales, options )

The abstract operation FilterLocales takes arguments availableLocales (一个 Available Locales List), requestedLocales (一个 Language Priority List), and options (一个 ECMAScript 语言值) and returns 要么是包含一个 Unicode 规范化 locale 标识符 List 的正常完成,要么是一个抛出完成. 它执行 BCP 47RFC 4647 section 3 中定义的 "filtering",返回 requestedLocales 中满足以下条件的元素:在使用 options 中指定的 LookupMatchingLocaleByBestFit 算法或 LookupMatchingLocaleByPrefix 算法时,availableLocales 包含匹配的 locale,同时保留其相对顺序。 It performs the following steps when called:

  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. 如果 match 不是 undefined,则将 locale 追加到 subset
  5. 返回 CreateArrayFromList(subset)。

9.2.10 CoerceOptionsToObject ( options )

The abstract operation CoerceOptionsToObject takes argument options (一个 ECMAScript 语言值) and returns 要么是包含一个 Object 的正常完成,要么是一个抛出完成. 它将 options 强制转换为适合与 GetOption 一起使用的 Object,默认为空 Object。 因为它会将非 null 原始值强制转换为对象,所以不鼓励新功能使用它,而应优先使用 GetOptionsObject。 It performs the following steps when called:

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

9.2.11 GetOption ( options, propertyKey, type, values, default )

The abstract operation GetOption takes arguments options (一个 Object), propertyKey (一个属性键), type (booleanstring), values (empty 或一个 ECMAScript 语言值的 List), and default (required 或一个 ECMAScript 语言值) and returns 要么是包含一个 ECMAScript 语言值的正常完成,要么是一个抛出完成. 它提取 options 的指定属性的值,将其转换为所需的 type,如果 values 不是 empty 则检查它是否被 values 允许,并在该值是 undefined 时替换为 default。 It performs the following steps when called:

  1. value 为 ? Get(options, propertyKey)。
  2. 如果 valueundefined,则
    1. 如果 defaultrequired,则抛出一个 TypeError 异常。
    2. 返回 default
  3. 如果 typeboolean,则
    1. value 设置为 ToBoolean(value)。
  4. 否则,
    1. 断言:typestring
    2. value 设置为 ? ToString(value)。
  5. 如果 values 不是 emptyvalues 不包含 value,则抛出一个 RangeError 异常。
  6. 返回 value

9.2.12 GetBooleanOrStringNumberFormatOption ( options, propertyKey, stringValues, fallback )

The abstract operation GetBooleanOrStringNumberFormatOption takes arguments options (一个 Object), propertyKey (一个属性键), stringValues (一个 Strings 的 List), and fallback (一个 ECMAScript 语言值) and returns 要么是包含 Boolean、String 或 fallback 之一的正常完成,要么是一个抛出完成. 它从提供的 options 对象中提取名为 propertyKey 的属性的值。如果该值是 undefined,则返回 fallback;如果该值是 true,则返回 true;如果该值强制转换为 false,则返回 false;否则将其强制转换为 String,并且如果其被 stringValues 允许,则返回结果。 It performs the following steps when called:

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

9.2.13 DefaultNumberOption ( value, minimum, maximum, fallback )

The abstract operation DefaultNumberOption takes arguments value (一个 ECMAScript 语言值), minimum (一个整数), maximum (一个整数), and fallback (一个整数或 undefined) and returns 要么是包含整数或 undefined 之一的正常完成,要么是一个抛出完成. 它将 value 转换为整数,检查它是否在允许范围内,并在必要时填入 fallback 值。 It performs the following steps when called:

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

9.2.14 GetNumberOption ( options, propertyKey, minimum, maximum, fallback )

The abstract operation GetNumberOption takes arguments options (一个 Object), propertyKey (一个 String), minimum (一个整数), maximum (一个整数), and fallback (一个整数或 undefined) and returns 要么是包含整数或 undefined 之一的正常完成,要么是一个抛出完成. 它从提供的 options 对象中提取名为 propertyKey 的属性的值,将其转换为整数,检查它是否在允许范围内,并在必要时填入 fallback 值。 It performs the following steps when called:

  1. value 为 ? Get(options, propertyKey)。
  2. 返回 ? DefaultNumberOption(value, minimum, maximum, fallback)。

9.2.15 PartitionPattern ( pattern )

The abstract operation PartitionPattern takes argument pattern (一个 Pattern String) and returns 一个带有字段 [[Type]](一个 String)和 [[Value]](一个 String 或 undefined)的 RecordsList. 如果 [[Type]]"literal",则 [[Value]] 字段将是一个 String 值;否则为 undefined。 It performs the following steps when called:

  1. result 为一个新的空 List
  2. placeholderEnd 为 -1。
  3. placeholderStartStringIndexOf(pattern, "{", 0)。
  4. 重复,当 placeholderStart 不是 not-found 时,
    1. literalpatternplaceholderEnd + 1 到 placeholderStart 的子字符串。
    2. 如果 literal 不是空 String,则
      1. Record { [[Type]]: "literal", [[Value]]: literal } 追加到 result
    3. placeholderEnd 设置为 StringIndexOf(pattern, "}", placeholderStart)。
    4. 断言:placeholderEnd 不是 not-foundplaceholderStart < placeholderEnd
    5. placeholderNamepatternplaceholderStart + 1 到 placeholderEnd 的子字符串。
    6. Record { [[Type]]: placeholderName, [[Value]]: undefined } 追加到 result
    7. placeholderStart 设置为 StringIndexOf(pattern, "{", placeholderEnd)。
  5. tailpatternplaceholderEnd + 1 开始的子字符串。
  6. 如果 tail 不是空 String,则
    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 ] ] )

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

  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 的 locale 数据来源取决于 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",则
  10. localeData%Intl.Collator%.[[SortLocaleData]]
  11. 否则,
  12. localeData%Intl.Collator%.[[SearchLocaleData]]
  13. optionsResolution 为 ? ResolveOptions(%Intl.Collator%, localeData, CreateArrayFromList(requestedLocales), options)。
  14. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  15. 设置 collator.[[Locale]]resolvedLocale .[[Locale]]
  16. 如果 resolvedLocale .[[co]]null,令 collation"default"。否则,令 collationresolvedLocale .[[co]]
  17. 设置 collator.[[Collation]]collation
  18. 设置 collator.[[Numeric]]SameValue(resolvedLocale .[[kn]], "true")。
  19. 设置 collator.[[CaseFirst]]resolvedLocale .[[kf]]
  20. resolvedLocaleDataresolvedLocale .[[LocaleData]]
  21. 如果 usage"sort",令 defaultSensitivity"variant"。否则,令 defaultSensitivityresolvedLocaleData.[[sensitivity]]
  22. 设置 collator.[[Sensitivity]] 为 ? GetOption(options, "sensitivity", string, « "base", "accent", "case", "variant" », defaultSensitivity)。
  23. defaultIgnorePunctuationresolvedLocaleData.[[ignorePunctuation]]
  24. 设置 collator.[[IgnorePunctuation]] 为 ? GetOption(options, "ignorePunctuation", boolean, empty, defaultIgnorePunctuation)。
  25. 返回 collator
Note
"search" 用法选项关联的排序方式只应用于查找匹配字符串,因为该排序方式不保证任何特定顺序。此行为在 Unicode 技术标准 #35 第1部分核心,Unicode Collation IdentifierUnicode 技术标准 #10 Unicode Collation Algorithm,搜索与匹配 中描述。

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 ] )

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

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

10.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 描述的约束范围内由实现定义。[[RelevantExtensionKeys]] 内部槽的值是一个列表,必须包含元素 "co",可以包含 "kf""kn" 元素中的任意一个或全部,且不得包含其他元素。

Note
Unicode 技术标准 #35 第1部分核心,3.6.1节 键和值定义 描述了与排序相关的十个区域扩展键:"co" 用于排序器用途和特化,"ka" 用于替代处理,"kb" 用于反向二级权重,"kc" 用于大小写级别,"kf" 用于首字母大小写,"kh" 用于平假名四级,"kk" 用于归一化,"kn" 用于数字,"kr" 用于重排序,"ks" 用于排序强度,以及 "vt" 用于变量顶。Collator 要求通过 options 对象的 "usage" 属性指定用途,通过 "ignorePunctuation" 属性指定替代处理,通过 "sensitivity" 属性指定大小写级别和强度。语言标签中的 "co" 键仅支持排序器特化,"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]] 列表的元素。
  • [[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. Table 3 的每一行(除表头行),按表顺序,执行
  5. propertyKey 为当前行的 Property 值。
  6. valuecollator 的内部槽,其名称为当前行的 Internal Slot 值。
  7. 如果当前行有 Extension Key 值,则
  8. extensionKey 为当前行的 Extension Key 值。
  9. 如果 %Intl.Collator%.[[RelevantExtensionKeys]] 不包含 extensionKey,则
  10. 设置 valueundefined
  11. 如果 value 不为 undefined,则
  12. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  13. 返回 options
Table 3: Collator 实例的已解析选项
内部槽 属性 扩展键
[[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 是一个访问器属性,其 set 访问器函数为 undefined。其 get 访问器函数执行以下步骤:

  1. collatorthis 值。
  2. 执行 ? RequireInternalSlot(collator, [[InitializedCollator]])。
  3. 如果 collator.[[BoundCompare]]undefined,则
  4. func 为一个新的内置函数对象,如 10.3.3.1 所定义。
  5. 设置 func.[[Collator]]collator
  6. 设置 collator.[[BoundCompare]]func
  7. 返回 collator.[[BoundCompare]]
Note
返回的函数绑定到 collator,因此可以直接传递给 Array.prototype.sort 或其他函数。

10.3.3.1 Collator 比较函数

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

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

  1. collatorfunc.[[Collator]]
  2. 断言:collator 是一个对象且具有 [[InitializedCollator]] 内部槽。
  3. 如果未提供 x,令 xundefined
  4. 如果未提供 y,令 yundefined
  5. xString 为 ? ToString(x)。
  6. yString 为 ? ToString(y)。
  7. 返回 CompareStrings(collator, xString, yString)。

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

10.3.3.2 CompareStrings ( collator, x, y )

The implementation-defined abstract operation CompareStrings takes arguments collator (一个 Intl.Collator), x (一个字符串), and y (一个字符串) and returns 一个数字,但不是 NaN.

如下所述的行为依赖于区域敏感地识别字符串的排序元素序列,特别是“基本字母”,不同的基本字母总是比较为不相等(导致包含它们的字符串也比较为不相等)。同一基本字母的不同变体(大小写、变音符号等)比较结果进一步取决于 collator.[[Sensitivity]],如下:

Table 4: Collator 敏感度的影响
[[Sensitivity]] 描述 "a""á" 比较 "a""A" 比较
"base" 具有相同基本字母的字符不比较为不相等,无论大小写或变音符号差异。 相等 相等
"accent" 具有相同基本字母的字符仅在变音符号等差异时比较为不相等,无论大小写。 不相等 相等
"case" 具有相同基本字母的字符仅在大小写差异时比较为不相等,无论变音符号。 相等 不相等
"variant" 具有相同基本字母的字符在大小写、变音符号及其他差异时比较为不相等。 不相等 不相等
Note 1
输入代码点到基本字母的映射可以包含任意收缩、扩展和冲突,包括对某些带变音符号字符的特殊处理。例如,在瑞典语中,“ö”是与“o”不同的基本字母,“v”和“w”被视为同一基本字母。在斯洛伐克语中,“ch”是一个基本字母,在英语中,“æ”是以“a”开头、“e”结尾的基本字母序列。

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

关于通过区域扩展键设置的选项解释,请参见 Unicode 技术标准 #35 第1部分核心,3.6.1节 键和值定义

实际返回值由实现定义,以允许编码附加信息,但对于任何给定 collator,作为 xy 的函数,该操作必须是一个一致的比较器,在所有字符串集合上定义一个全序。该操作还必须识别并遵循 Unicode 标准的规范等价,包括在比较可区分但规范等价的字符串时返回 +0𝔽

Note 2
推荐 CompareStrings 抽象操作按照 Unicode 技术标准 #10:Unicode Collation Algorithm 实现,并针对 collator 的有效区域和排序选项进行定制。推荐实现使用由 Common Locale Data Repository 提供的定制(https://cldr.unicode.org/)。
Note 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",标识排序器用途。
  • [[Sensitivity]] 是字符串值 "base""accent""case""variant",标识排序器的敏感度。
  • [[IgnorePunctuation]] 是布尔值,指定比较时是否忽略标点。
  • [[Collation]] 是一个字符串值,表示用于排序的 Unicode Collation Identifier"standard""search" 不允许,"default" 允许。

如果 Table 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 ] ] )

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

  1. 如果 NewTarget 是 undefined,令 newTarget 为活动函数对象,否则令 newTarget 为 NewTarget。
  2. dateTimeFormat 为 ? CreateDateTimeFormat(newTarget, locales, options, any, date)。
  3. 如果实现支持 4.3 Note 1 的规范可选构造函数模式,则
    1. thisthis 值。
    2. 返回 ? ChainDateTimeFormat(dateTimeFormat, NewTarget, this)。
  4. 返回 dateTimeFormat

11.1.1.1 ChainDateTimeFormat ( dateTimeFormat, newTarget, this )

The abstract operation ChainDateTimeFormat takes arguments dateTimeFormat (一个 Intl.DateTimeFormat), newTarget (一个 ECMAScript 语言值), and this (一个 ECMAScript 语言值) and returns 包含 Object 的正常完成或抛出完成. It performs the following steps when called:

  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 )

The abstract operation CreateDateTimeFormat takes arguments newTarget (一个构造函数), locales (一个 ECMAScript 语言值), options (一个 ECMAScript 语言值), required (datetimeany), and defaults (datetimeall) and returns 包含 DateTimeFormat 对象的正常完成或抛出完成. It performs the following steps when called:

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

11.1.3 FormatOffsetTimeZoneIdentifier ( offsetMinutes )

The abstract operation FormatOffsetTimeZoneIdentifier takes argument offsetMinutes (一个整数) and returns 一个 String. It performs the following steps when called:

  1. 如果 offsetMinutes ≥ 0,令 sign 为码元 0x002B (PLUS SIGN);否则令 sign 为码元 0x002D (HYPHEN-MINUS)。
  2. absoluteMinutesabs(offsetMinutes)。
  3. hoursfloor(absoluteMinutes / 60)。
  4. minutesabsoluteMinutes modulo 60。
  5. 返回 signToZeroPaddedDecimalString(hours, 2)、码元 0x003A (COLON) 以及 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 ] )

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

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

11.2.3 内部槽

[[AvailableLocales]] 内部槽的值是在 9.1 中所述约束内由实现定义的。

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

Note 1
Unicode 技术标准 #35 第 1 部分 Core,第 3.6.1 节 Key and Type Definitions 描述了四个与日期和时间格式化相关的语言环境扩展键:"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>]] 字段的值必须是一个 DateTime Format RecordsList。此类 List 中的多个 Record 可以使用相同的字段子集,只要对应值至少在一个字段上不同。每个语言环境必须提供以下子集:
    • 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 都具有 Table 5 中定义的字段。

Table 5: DateTime Format Record
字段名 值类型 描述
[[weekday]] Table 16 的 Values 列中的 [[Weekday]] 可选字段。如果 [[pattern]] 包含子字符串 "{weekday}",则存在。
[[era]] Table 16 的 Values 列中的 [[Era]] 可选字段。如果 [[pattern]] 包含子字符串 "{era}",则存在。
[[year]] Table 16 的 Values 列中的 [[Year]] 可选字段。如果 [[pattern]] 包含子字符串 "{year}""{yearName}""{relatedYear}" 中至少一个,则存在。
[[month]] Table 16 的 Values 列中的 [[Month]] 可选字段。如果 [[pattern]] 包含子字符串 "{month}",则存在。
[[day]] Table 16 的 Values 列中的 [[Day]] 可选字段。如果 [[pattern]] 包含子字符串 "{day}",则存在。
[[dayPeriod]] Table 16 的 Values 列中的 [[DayPeriod]] 可选字段。如果 [[pattern]] 包含子字符串 "{dayPeriod}",则存在。
[[hour]] Table 16 的 Values 列中的 [[Hour]] 可选字段。如果 [[pattern]] 包含子字符串 "{hour}",则存在。
[[minute]] Table 16 的 Values 列中的 [[Minute]] 可选字段。如果 [[pattern]] 包含子字符串 "{minute}",则存在。
[[second]] Table 16 的 Values 列中的 [[Second]] 可选字段。如果 [[pattern]] 包含子字符串 "{second}",则存在。
[[fractionalSecondDigits]] Table 16 的 Values 列中的 [[FractionalSecondDigits]] 可选字段。如果 [[pattern]] 包含子字符串 "{fractionalSecondDigits}",则存在。
[[timeZoneName]] Table 16 的 Values 列中的 [[TimeZoneName]] 可选字段。如果 [[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 都具有 Table 6 中定义的字段。

Table 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 都具有 Table 7 中定义的字段。

Table 7: DateTime Range Pattern Format Record
字段名 值类型 描述
[[weekday]] Table 16 的 Values 列中的 [[Weekday]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{weekday}",则存在。
[[era]] Table 16 的 Values 列中的 [[Era]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{era}",则存在。
[[year]] Table 16 的 Values 列中的 [[Year]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{year}""{yearName}""{relatedYear}" 中至少一个,则存在。
[[month]] Table 16 的 Values 列中的 [[Month]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{month}",则存在。
[[day]] Table 16 的 Values 列中的 [[Day]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{day}",则存在。
[[dayPeriod]] Table 16 的 Values 列中的 [[DayPeriod]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{dayPeriod}",则存在。
[[hour]] Table 16 的 Values 列中的 [[Hour]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{hour}",则存在。
[[minute]] Table 16 的 Values 列中的 [[Minute]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{minute}",则存在。
[[second]] Table 16 的 Values 列中的 [[Second]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{second}",则存在。
[[fractionalSecondDigits]] Table 16 的 Values 列中的 [[FractionalSecondDigits]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{fractionalSecondDigits}",则存在。
[[timeZoneName]] Table 16 的 Values 列中的 [[TimeZoneName]] 可选字段。如果 [[PatternParts]] 中的 Pattern String 包含子字符串 "{timeZoneName}",则存在。
[[PatternParts]] 一个 DateTime Range Pattern Part RecordsList 每个记录表示范围模式的一部分。

11.2.3.4 DateTime Range Pattern Part Records

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

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

11.2.3.5 DateTime Styles Records

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

Table 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 都具有 Table 10 中定义的字段。

Table 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 都具有 Table 11 中定义的字段。所有连接器模式字符串都必须包含字符串 "{0}""{1}"

Table 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 都具有 Table 12 中定义的字段。

Table 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 都具有 Table 13 中定义的字段。

Table 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 都具有 Table 14 中定义的字段。

Table 14: DateTime Style Range Record
字段名 值类型 描述
[[rangePatterns]] 一个 DateTime Range Pattern Record 用于组合日期和时间样式的范围模式。
[[rangePatterns12]] 一个 DateTime Range Pattern Record 可选字段。用于为 12 小时格式组合日期和时间样式的范围模式。
Note 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}"}
Note 3
建议实现使用 Common Locale Data Repository 提供的语言环境数据(可在 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 Note 1 的规范可选构造函数模式,则
    1. dtf 设为 ? UnwrapDateTimeFormat(dtf)。
  3. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  4. optionsOrdinaryObjectCreate(%Object.prototype%)。
  5. Table 15 的每一行(表头行除外),按表格顺序执行
    1. propertyKey 为当前行的 Property 值。
    2. 如果当前行中有 Internal Slot 值,则
      1. valuedtf 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 否则,
      1. formatdtf.[[DateTimeFormat]]
      2. 如果 format 具有字段 [[<propertyKey>]],并且 dtf.[[DateStyle]]undefineddtf.[[TimeStyle]]undefined,则
        1. valueformat.[[<propertyKey>]]。
      3. 否则,
        1. valueundefined
    4. 如果 value 不是 undefined,则
      1. 如果当前行中有 Conversion 值,则
        1. conversion 为当前行的 Conversion 值。
        2. 如果 conversionhour12,则
          1. 如果 value"h11""h12",将 value 设为 true。否则,将 value 设为 false
        3. 否则,
          1. 断言:conversionnumber
          2. value 设为 𝔽(value)。
      2. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  6. 返回 options
Table 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"

出于 Web 兼容性原因,如果设置了 "hourCycle" 属性,则当 "hourCycle""h11""h12" 时,应将 "hour12" 属性设为 true;当 "hourCycle""h23""h24" 时,应将其设为 false

Note 1
在此版本的 API 中,如果没有在提供给 Intl.DateTimeFormat 构造函数的选项对象中提供 "timeZone" 属性,那么 "timeZone" 属性将是宿主环境时区的标识符。第一版在这种情况下将 "timeZone" 属性保留为 undefined
Note 2
为了与第五版之前的版本兼容,除了 "hourCycle" 属性外,还会设置 "hour12" 属性。

11.3.3 get Intl.DateTimeFormat.prototype.format

Intl.DateTimeFormat.prototype.format 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

  1. dtfthis 值。
  2. 如果实现支持 4.3 Note 1 的规范可选构造函数模式,则
    1. dtf 设为 ? UnwrapDateTimeFormat(dtf)。
  3. 执行 ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]])。
  4. 如果 dtf.[[BoundFormat]]undefined,则
    1. func 为一个新的内置函数对象,如 DateTime Format Functions(11.5.4)中所定义。
    2. func.[[DateTimeFormat]] 设为 dtf
    3. dtf.[[BoundFormat]] 设为 func
  5. 返回 dtf.[[BoundFormat]]
Note
返回的函数绑定到 dtf,因此它可以直接传递给 Array.prototype.map 或其他函数。 这被视为一个历史遗留物,是一种已不再为新特性遵循的约定的一部分,但为保持与现有程序兼容而保留。

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

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

  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 )

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

  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 )

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

  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 构造函数 计算:

  • [[Locale]] 是一个 String,表示用于格式化的本地化所用语言环境的语言标签
  • [[Calendar]] 是一个 String,表示用于格式化的 Unicode Calendar Identifier
  • [[NumberingSystem]] 是一个 String,表示用于格式化的 Unicode Number System Identifier
  • [[TimeZone]] 是一个用于格式化的 String,它是可用的具名时区标识符或偏移时区标识符。
  • [[HourCycle]] 是一个 String,指示应使用 12 小时格式("h11""h12")还是 24 小时格式("h23""h24")。"h11""h23" 分别从小时 0 开始,并分别递增到 11 和 23。"h12""h24" 从小时 1 开始,并分别递增到 12 和 24。[[HourCycle]] 仅在 [[DateTimeFormat]] 具有 [[hour]] 字段时使用。
  • [[DateStyle]][[TimeStyle]] 各自要么是 undefined,要么是 "full""long""medium""short"
  • [[DateTimeFormat]] 是一个 DateTime Format Record

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

11.5 DateTimeFormat 对象的抽象操作

若干 DateTimeFormat 算法使用下表中的值,该表为日期和时间格式的组件提供内部槽、属性名和允许值:

Table 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 )

The abstract operation DateTimeStyleFormat takes arguments dateStyle ("full""long""medium""short"undefined), timeStyle ("full""long""medium""short"undefined), and styles (一个 DateTime Styles Record) and returns 一个 DateTime Format Record. It performs the following steps when called:

  1. 断言:dateStyle 不是 undefinedtimeStyle 不是 undefined
  2. 如果 timeStyle 不是 undefined,则
    1. 断言:timeStyle"full""long""medium""short" 之一。
    2. timeFormatstyles.[[Time]].[[<timeStyle>]]。
  3. 如果 dateStyle 不是 undefined,则
    1. 断言:dateStyle"full""long""medium""short" 之一。
    2. dateFormatstyles.[[Date]].[[<dateStyle>]]。
  4. 如果 dateStyle 不是 undefinedtimeStyle 不是 undefined,则
    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. 如果 timeStyle 不是 undefined,则
    1. 返回 timeFormat
  6. 断言:dateStyle 不是 undefined
  7. 返回 dateFormat

11.5.2 BasicFormatMatcher ( options, formats )

The abstract operation BasicFormatMatcher takes arguments options (一个 Record) and formats (一个 DateTime Format RecordsList) and returns 一个 DateTime Format Record. It performs the following steps when called:

  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. Table 16 的每一行(表头行除外),按表格顺序执行
      1. property 为当前行 Property 列中给出的名称。
      2. 如果 options 具有字段 [[<property>]],令 optionsPropoptions.[[<property>]];否则令 optionsPropundefined
      3. 如果 format 具有字段 [[<property>]],令 formatPropformat.[[<property>]];否则令 formatPropundefined
      4. 如果 optionsPropundefinedformatProp 不是 undefined,则
        1. score 设为 score - additionPenalty
      5. 否则如果 optionsProp 不是 undefinedformatPropundefined,则
        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 )

The implementation-defined abstract operation BestFitFormatMatcher takes arguments options (一个 Record) and formats (一个 DateTime Format RecordsList) and returns 一个 DateTime Format Record.

11.5.4 DateTime 格式函数

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

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

  1. dtffunc.[[DateTimeFormat]]
  2. 断言:dtf 是一个 Object,并且 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 )

The abstract operation FormatDateTimePattern takes arguments dateTimeFormat (一个 Intl.DateTimeFormat), format (一个 DateTime Format RecordDateTime Range Pattern Format Record), pattern (一个 Pattern String), and epochNanoseconds (一个 BigInt) and returns 具有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList. It performs the following steps when called:

  1. localedateTimeFormat.[[Locale]]
  2. nfOptionsOrdinaryObjectCreate(null)。
  3. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", dateTimeFormat.[[NumberingSystem]])。
  4. 执行 ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false)。
  5. nf 为 ! Construct(%Intl.NumberFormat%, « locale, nfOptions »)。
  6. nf2OptionsOrdinaryObjectCreate(null)。
  7. 执行 ! CreateDataPropertyOrThrow(nf2Options, "minimumIntegerDigits", 2𝔽)。
  8. 执行 ! CreateDataPropertyOrThrow(nf2Options, "numberingSystem", dateTimeFormat.[[NumberingSystem]])。
  9. 执行 ! CreateDataPropertyOrThrow(nf2Options, "useGrouping", false)。
  10. nf2 为 ! Construct(%Intl.NumberFormat%, « locale, nf2Options »)。
  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%, « locale, nf3Options »)。
  12. localTimeToLocalTime(epochNanoseconds, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]])。
  13. patternPartsPartitionPattern(pattern)。
  14. result 为一个新的空 List
  15. patternParts 的每个 Record { [[Type]], [[Value]] } patternPart,执行
    1. partTypepatternPart.[[Type]]
    2. 如果 partType"literal",则
      1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } 追加到 result
    3. 否则如果 partType"fractionalSecondDigits",则
      1. 断言:format 具有字段 [[fractionalSecondDigits]]
      2. valuelocalTime.[[Millisecond]]
      3. value 设为 floor(value × 10( fractionalSecondDigits - 3 ))。
      4. formattedValueFormatNumeric(nf3, value)。
      5. Record { [[Type]]: "fractionalSecond", [[Value]]: formattedValue } 追加到 result
    4. 否则如果 partType"dayPeriod",则
      1. 断言:format 具有字段 [[dayPeriod]]
      2. fieldFormatformat.[[dayPeriod]]
      3. formattedValue 为一个 ILD String,表示 localTime 的日期时段,其形式由 fieldFormat 给出。
      4. Record { [[Type]]: partType, [[Value]]: formattedValue } 追加到 result
    5. 否则如果 partType"timeZoneName",则
      1. 断言:format 具有字段 [[timeZoneName]]
      2. fieldFormatformat.[[timeZoneName]]
      3. valuedateTimeFormat.[[TimeZone]]
      4. formattedValue 为一个 ILD String,表示 value,其形式由 fieldFormat 给出。如果 fieldFormat"short""long""shortOffset""longOffset",其值可能取决于 localTime[[InDST]] 字段的值。如果实现没有 fieldFormat 的此类本地化表示,则使用 value 自身。
      5. Record { [[Type]]: partType, [[Value]]: formattedValue } 追加到 result
    6. 否则如果 partType 匹配 Table 16 中某一行的 Property 列,则
      1. 断言:format 具有字段 [[<partType>]]。
      2. fieldFormatformat.[[<partType>]]。
      3. valuelocalTime 中名称为匹配行 Internal Slot 列的字段的值。
      4. 如果 partType"year"value ≤ 0,将 value 设为 1 - value
      5. 如果 partType"month",将 value 设为 value + 1。
      6. 如果 partType"hour"dateTimeFormat.[[HourCycle]]"h11""h12",则
        1. value 设为 value modulo 12。
        2. 如果 value = 0 且 dateTimeFormat.[[HourCycle]]"h12",将 value 设为 12。
      7. 如果 partType"hour"dateTimeFormat.[[HourCycle]]"h24",则
        1. 如果 value = 0,将 value 设为 24。
      8. 如果 fieldFormat"numeric",则
        1. formattedValueFormatNumeric(nf, value)。
      9. 否则如果 fieldFormat"2-digit",则
        1. formattedValueFormatNumeric(nf2, value)。
        2. codePointsStringToCodePoints(formattedValue)。
        3. countcodePoints 中元素的数量。
        4. 如果 count > 2,则
          1. tenscodePoints[count - 2]。
          2. onescodePoints[count - 1]。
          3. formattedValue 设为 CodePointsToStringtens, ones »)。
      10. 否则如果 fieldFormat"narrow""short""long",则
        1. formattedValue 为一个 ILD String,表示 value,其形式由 fieldFormat 给出。如果 partType"month",则其值可能取决于 format 是否具有 [[day]] 字段。如果实现没有 fieldFormat 的本地化表示,则使用 value 自身。
      11. Record { [[Type]]: partType, [[Value]]: formattedValue } 追加到 result
    7. 否则如果 partType"ampm",则
      1. valuelocalTime.[[Hour]]
      2. 如果 value > 11,令 formattedValue 为表示 "post meridiem"ILD String;否则令 formattedValue 为表示 "ante meridiem"ILD String。
      3. Record { [[Type]]: "dayPeriod", [[Value]]: formattedValue } 追加到 result
    8. 否则如果 partType"relatedYear",则
      1. valuelocalTime.[[RelatedYear]]
      2. formattedValueFormatNumeric(nf, value)。
      3. Record { [[Type]]: "relatedYear", [[Value]]: formattedValue } 追加到 result
    9. 否则如果 partType"yearName",则
      1. valuelocalTime.[[YearName]]
      2. formattedValue 为表示 valueILD String。
      3. Record { [[Type]]: "yearName", [[Value]]: formattedValue } 追加到 result
    10. 否则,
      1. unknown 为基于 epochNanosecondspartTypeILND String。
      2. Record { [[Type]]: "unknown", [[Value]]: unknown } 追加到 result
  16. 返回 result
Note
建议实现使用 Common Locale Data Repository 提供的依赖于语言环境和日历的字符串(可在 https://cldr.unicode.org/ 获得),并将 CLDR "abbreviated" 字符串用于 DateTimeFormat "short" 字符串,将 CLDR "wide" 字符串用于 DateTimeFormat "long" 字符串。

11.5.6 PartitionDateTimePattern ( dateTimeFormat, x )

The abstract operation PartitionDateTimePattern takes arguments dateTimeFormat (一个 Intl.DateTimeFormat) and x (一个 Number) and returns 包含具有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList 的正常完成,或抛出完成. It performs the following steps when called:

  1. x 设为 TimeClip(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(dateTimeFormat, format, pattern, epochNanoseconds)。
  8. 返回 result

11.5.7 FormatDateTime ( dateTimeFormat, x )

The abstract operation FormatDateTime takes arguments dateTimeFormat (一个 Intl.DateTimeFormat) and x (一个 Number) and returns 包含 String 的正常完成或抛出完成. It performs the following steps when called:

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

11.5.8 FormatDateTimeToParts ( dateTimeFormat, x )

The abstract operation FormatDateTimeToParts takes arguments dateTimeFormat (一个 Intl.DateTimeFormat) and x (一个 Number) and returns 包含 Array 的正常完成或抛出完成. It performs the following steps when called:

  1. parts 为 ? PartitionDateTimePattern(dateTimeFormat, x)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]] } part,执行
    1. partObjOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(partObj, "type", part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(partObj, "value", part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), partObj)。
    5. n 设为 n + 1。
  5. 返回 result

11.5.9 PartitionDateTimeRangePattern ( dateTimeFormat, x, y )

The abstract operation PartitionDateTimeRangePattern takes arguments dateTimeFormat (一个 Intl.DateTimeFormat), x (一个 Number), and y (一个 Number) and returns 包含具有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Source]](一个 String)的 RecordsList 的正常完成,或抛出完成. It performs the following steps when called:

  1. x 设为 TimeClip(x)。
  2. 如果 xNaN,则抛出一个 RangeError 异常。
  3. y 设为 TimeClip(y)。
  4. 如果 yNaN,则抛出一个 RangeError 异常。
  5. xEpochNanoseconds((x) × 106)。
  6. yEpochNanoseconds((y) × 106)。
  7. localTime1ToLocalTime(xEpochNanoseconds, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]])。
  8. localTime2ToLocalTime(yEpochNanoseconds, dateTimeFormat.[[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. Table 6 的每一行(表头行除外),按表格顺序执行
    1. fieldName 为该行 Field Name 列中给出的名称。
    2. 如果 rangePatterns 具有名称为 fieldName 的字段,令 rangePatternrangePatterns 中名称为 fieldName 的字段;否则令 rangePatternundefined
    3. 如果 selectedRangePattern 不是 undefinedrangePatternundefined,则
      1. 注:因为对于此字段及其以下的差异没有范围模式,所以不会执行进一步检查。
      2. checkMoreFields 设为 false
    4. 如果 fieldName 不等于 [[Default]],并且 relevantFieldsEqualtruecheckMoreFieldstrue,则
      1. selectedRangePattern 设为 rangePattern
      2. 如果 fieldName[[AmPm]],则
        1. 如果 localTime1.[[Hour]] 小于 12,令 v1"am";否则令 v1"pm"
        2. 如果 localTime2.[[Hour]] 小于 12,令 v2"am";否则令 v2"pm"
      3. 否则如果 fieldName[[DayPeriod]],则
        1. v1 为表示 localTime1 的日期时段的 ILD String。
        2. v2 为表示 localTime2 的日期时段的 ILD String。
      4. 否则如果 fieldName[[FractionalSecondDigits]],则
        1. 如果 format 具有 [[fractionalSecondDigits]] 字段,则
          1. fractionalSecondDigitsformat.[[fractionalSecondDigits]]
        2. 否则,
          1. fractionalSecondDigits 为 3。
        3. expfractionalSecondDigits - 3。
        4. v1floor(localTime1.[[Millisecond]] × 10exp)。
        5. v2floor(localTime2.[[Millisecond]] × 10exp)。
      5. 否则,
        1. v1localTime1 中名称为 fieldName 的字段。
        2. v2localTime2 中名称为 fieldName 的字段。
      6. 如果 v1 不等于 v2,则
        1. relevantFieldsEqual 设为 false
  16. 如果 relevantFieldsEqualtrue,则
    1. collapsedResult 为一个新的空 List
    2. resultPartsFormatDateTimePattern(dateTimeFormat, format, pattern, xEpochNanoseconds)。
    3. resultParts 的每个 Record { [[Type]], [[Value]] } part,执行
      1. Record { [[Type]]: part.[[Type]], [[Value]]: part.[[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(dateTimeFormat, selectedRangePattern, pattern, z)。
    6. resultParts 的每个 Record { [[Type]], [[Value]] } part,执行
      1. Record { [[Type]]: part.[[Type]], [[Value]]: part.[[Value]], [[Source]]: source } 追加到 rangeResult
  20. 返回 rangeResult

11.5.10 FormatDateTimeRange ( dateTimeFormat, x, y )

The abstract operation FormatDateTimeRange takes arguments dateTimeFormat (一个 Intl.DateTimeFormat), x (一个 Number), and y (一个 Number) and returns 包含 String 的正常完成或抛出完成. It performs the following steps when called:

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

11.5.11 FormatDateTimeRangeToParts ( dateTimeFormat, x, y )

The abstract operation FormatDateTimeRangeToParts takes arguments dateTimeFormat (一个 Intl.DateTimeFormat), x (一个 Number), and y (一个 Number) and returns 包含 Array 的正常完成或抛出完成. It performs the following steps when called:

  1. parts 为 ? PartitionDateTimeRangePattern(dateTimeFormat, x, y)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]], [[Source]] } part,执行
    1. partObjOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(partObj, "type", part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(partObj, "value", part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(partObj, "source", part.[[Source]])。
    5. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), partObj)。
    6. n 设为 n + 1。
  5. 返回 result

11.5.12 ToLocalTime ( epochNs, calendar, timeZoneIdentifier )

The implementation-defined abstract operation ToLocalTime takes arguments epochNs (一个 BigInt), calendar (一个 String), and timeZoneIdentifier (一个 String) and returns 一个 ToLocalTime Record. It performs the following steps when called:

  1. 如果 IsTimeZoneOffsetString(timeZoneIdentifier) 是 true,则
    1. offsetNsParseTimeZoneOffsetString(timeZoneIdentifier)。
  2. 否则,
    1. 断言:GetAvailableNamedTimeZoneIdentifier(timeZoneIdentifier) 不是 empty
    2. offsetNsGetNamedTimeZoneOffsetNanoseconds(timeZoneIdentifier, epochNs)。
  3. tz(epochNs) + offsetNs
  4. 如果 calendar"gregory",则
    1. 返回一个 ToLocalTime Record,其字段根据 Table 17tz 计算得到。
  5. 否则,
    1. 返回一个 ToLocalTime Record,其字段是针对给定 calendartz 计算得到的。这些计算应使用关于指定 calendar 的最佳可用信息。

11.5.13 ToLocalTime Records

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

Table 17: ToLocalTime 返回的记录
字段名 值类型 公历日历的值计算
[[Weekday]] 一个整数 (WeekDay(𝔽(floor(tz / 106))))
[[Era]] 一个 String yearYearFromTime(𝔽(floor(tz / 106)))。如果 year < 1𝔽,返回 "BC",否则返回 "AD"
[[Year]] 一个整数 (YearFromTime(𝔽(floor(tz / 106))))
[[RelatedYear]] 一个整数或 undefined undefined
[[YearName]] 一个 String 或 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]] 一个 Boolean 使用关于指定 calendartimeZoneIdentifier 的最佳可用信息计算 truefalse,包括来自 IANA Time Zone Database 的关于 UTC 时区偏移和夏令时规则的当前及历史信息。

11.5.14 UnwrapDateTimeFormat ( dtf )

The abstract operation UnwrapDateTimeFormat takes argument dtf (一个 ECMAScript 语言值) and returns 包含 ECMAScript 语言值的正常完成或抛出完成. It performs the following steps when called:

  1. 如果 dtf 不是一个 Object,则抛出一个 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 )

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

  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]], locales, options, « require-options »)。
  4. options 设置为 optionsResolution.[[Options]]
  5. resolvedLocaleoptionsResolution.[[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" », required)。
  9. displayNames.[[Type]] 设置为 type
  10. fallback 为 ? GetOption(options, "fallback", string, « "code", "none" », "code")。
  11. displayNames.[[Fallback]] 设置为 fallback
  12. displayNames.[[Locale]] 设置为 resolvedLocale.[[Locale]]
  13. resolvedLocaleDataresolvedLocale.[[LocaleData]]
  14. typesresolvedLocaleData.[[types]]
  15. 断言:types 是一个 Record(参见 12.2.3)。
  16. languageDisplay 为 ? GetOption(options, "languageDisplay", string, « "dialect", "standard" », "dialect")。
  17. typeFieldstypes.[[<type>]]。
  18. 断言:typeFields 是一个 Record(参见 12.2.3)。
  19. 如果 type"language",则
    1. displayNames.[[LanguageDisplay]] 设置为 languageDisplay
    2. typeFields 设置为 typeFields.[[<languageDisplay>]]。
    3. 断言:typeFields 是一个 Record(参见 12.2.3)。
  20. styleFieldstypeFields.[[<style>]]。
  21. 断言:styleFields 是一个 Record(参见 12.2.3)。
  22. displayNames.[[Fields]] 设置为 styleFields
  23. 返回 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 ] )

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

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

12.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 中描述的约束范围内由实现定义。

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

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

[[LocaleData]] 内部槽的值在 9.1 中描述的约束范围内由实现定义,并满足以下额外约束:

  • 对于所有 locale 值 locale[[LocaleData]].[[<locale>]] 必须具有一个 [[types]] 字段。该字段的值必须是一个 Record,它必须具有名称为所有显示名称类型的字段:"language""region""script""currency""calendar""dateTimeField"
  • 字段 "language" 的值必须是一个 Record,它必须具有名称为有效语言显示之一的字段:"dialect""standard"
  • 显示名称类型 "language" 下的语言显示字段应包含 Record,这些 Record 必须具有名称为有效显示名称样式之一的字段:"narrow""short""long"
  • 字段 "region""script""currency""calendar""dateTimeField" 的值必须是 Record,这些 Record 必须具有名称为所有显示名称样式的字段:"narrow""short""long"
  • 显示名称类型 "language" 下的显示名称样式字段应包含 Record,其键对应于可由 unicode_language_id Unicode locale 非终结符匹配的语言代码。这些字段的值必须是字符串值。
  • 显示名称类型 "region" 下的显示名称样式字段应包含 Record,其键对应于地区代码。这些字段的值必须是字符串值。
  • 显示名称类型 "script" 下的显示名称样式字段应包含 Record,其键对应于书写系统代码。这些字段的值必须是字符串值。
  • 显示名称类型 "currency" 下的显示名称样式字段应包含 Record,其键对应于货币代码。这些字段的值必须是字符串值。
  • 显示名称类型 "calendar" 下的显示名称样式字段应包含 Record,其键对应于可由 type Unicode locale 非终结符匹配的日历标识符。这些字段的值必须是字符串值。
  • 显示名称类型 "dateTimeField" 下的显示名称样式字段应包含 Record,其键对应于 Table 19 中列出的代码。这些字段的值必须是字符串值。
Note
建议实现使用 Common Locale Data Repository 提供的 locale 数据(可在 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 ( )

该函数提供对对象初始化期间计算出的 locale 和选项的访问。

  1. displayNamesthis 值。
  2. 执行 ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. Table 18 的每一行(表头行除外),按表格顺序,执行
    1. propertyKey 为当前行的 Property 值。
    2. valuedisplayNames 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 如果 value 不是 undefined,则
      1. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  5. 返回 options
Table 18: DisplayNames 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[Style]] "style"
[[Type]] "type"
[[Fallback]] "fallback"
[[LanguageDisplay]] "languageDisplay"

12.3.3 Intl.DisplayNames.prototype.of ( code )

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

  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% 属性的初始值是 String 值 "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]] 是一个 String 值,带有其本地化用于格式化的 locale 的语言标签
  • [[Style]] 是 String 值 "narrow""short""long" 之一,用于标识所使用的显示名称样式。
  • [[Type]] 是 String 值 "language""region""script""currency""calendar""dateTimeField" 之一,用于标识所请求的显示名称类型。
  • [[Fallback]] 是 String 值 "code""none" 之一,用于标识系统没有所请求的显示名称时的回退返回值。
  • [[LanguageDisplay]] 是 String 值 "dialect""standard" 之一,用于标识语言显示种类。它仅在 [[Type]] 的值为 "language" 时使用。
  • [[Fields]] 是一个 Record(参见 12.2.3),它必须具有键对应于根据 [[Style]][[Type]][[LanguageDisplay]] 的代码的字段。

12.5 DisplayNames 对象的抽象操作

12.5.1 CanonicalCodeForDisplayNames ( type, code )

The abstract operation CanonicalCodeForDisplayNames takes arguments type (一个 String) and code (一个 String) and returns 要么是包含一个 String 的正常完成,要么是一个抛出完成. 它验证 code 是否表示符合 type 的格式良好的代码,并返回 code 的大小写规范化形式。 It performs the following steps when called:

  1. 如果 type"language",则
    1. 如果 code 不能由 unicode_language_id Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    2. 如果 IsWellFormedLanguageTag(code) 是 false,则抛出一个 RangeError 异常。
    3. 返回 CanonicalizeUnicodeLocaleId(code)。
  2. 如果 type"region",则
    1. 如果 code 不能由 unicode_region_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    2. 返回 code 的 ASCII 大写形式。
  3. 如果 type"script",则
    1. 如果 code 不能由 unicode_script_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    2. 断言:code 的长度为 4,且 code 的每个码元都表示一个 ASCII 字母(0x0041 到 0x005A 和 0x0061 到 0x007A,均包含在内)。
    3. firstcode 从 0 到 1 的子字符串的 ASCII 大写形式。
    4. restcode 从 1 开始的子字符串的 ASCII 小写形式。
    5. 返回 firstrest 的字符串拼接。
  4. 如果 type"calendar",则
    1. 如果 code 不能由 type Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    2. 如果 code 使用了 Unicode Technical Standard #35 Part 1 Core, Section 3.3 BCP 47 Conformance 中描述的任何向后兼容语法,则抛出一个 RangeError 异常。
    3. 返回 code 的 ASCII 小写形式。
  5. 如果 type"dateTimeField",则
    1. 如果 IsValidDateTimeFieldCode(code) 的结果是 false,则抛出一个 RangeError 异常。
    2. 返回 code
  6. 断言:type"currency"
  7. 如果 IsWellFormedCurrencyCode(code) 是 false,则抛出一个 RangeError 异常。
  8. 返回 code 的 ASCII 大写形式。

12.5.2 IsValidDateTimeFieldCode ( field )

The abstract operation IsValidDateTimeFieldCode takes argument field (一个 String) and returns 一个 Boolean. 它验证 field 实参是否表示一个有效的日期时间字段代码。 It performs the following steps when called:

  1. 如果 field 列在 Table 19 的 Code 列中,则返回 true
  2. 返回 false
Table 19: DisplayNames 的 Date Time Field 代码
Code 描述
"era" 表示 era 的字段,例如 Gregorian 或 Julian calendar 中的 AD 或 BC。
"year" 表示(某个 era 内)year 的字段。
"quarter" 表示 quarter 的字段,例如 Q2、2nd quarter 等。
"month" 表示 month 的字段,例如 Sep、September 等。
"weekOfYear" 表示一年中的周数的字段。
"weekday" 表示星期几的字段,例如 Tue、Tuesday 等。
"day" 表示月份中日期的字段。
"dayPeriod" 表示 day period 的字段,可以是 am、pm 等,也可以是 noon、evening 等。
"hour" 表示 hour 的字段。
"minute" 表示 minute 的字段。
"second" 表示 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 ] ] )

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

  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. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  6. durationFormat.[[Locale]] 设置为 resolvedLocale.[[Locale]]
  7. resolvedLocaleDataresolvedLocale.[[LocaleData]]
  8. digitalFormatresolvedLocaleData.[[DigitalFormat]]
  9. durationFormat.[[HourMinuteSeparator]] 设置为 digitalFormat.[[HourMinuteSeparator]]
  10. durationFormat.[[MinuteSecondSeparator]] 设置为 digitalFormat.[[MinuteSecondSeparator]]
  11. durationFormat.[[NumberingSystem]] 设置为 resolvedLocale.[[nu]]
  12. style 为 ? GetOption(options, "style", string, « "long", "short", "narrow", "digital" », "short")。
  13. durationFormat.[[Style]] 设置为 style
  14. prevStyle 为空 String。
  15. Table 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
Table 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 ] )

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

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

13.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 中描述的约束范围内由实现定义。

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

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

[[LocaleData]] 内部槽的值在 9.1 中描述的约束范围内由实现定义,并且对于所有 locale 值 locale,满足以下额外约束:

  • [[LocaleData]].[[<locale>]] 必须是具有字段 [[nu]][[DigitalFormat]]Record
  • [[LocaleData]].[[<locale>]].[[nu]] 必须是 16.2.3 中规定的 List,且不得包含值 "native""traditio""finance"
  • [[LocaleData]].[[<locale>]].[[DigitalFormat]] 必须是一个 Record,其键对应于 locale 可用的每个编号系统。与其中一个键关联的每个值都必须是包含以下字段的 Record
    • [[HourMinuteSeparator]] 必须是一个 String 值,表示在使用 "numeric""2-digit" 样式时,对于该 locale 与编号系统组合,在小时和分钟之间使用的适当分隔符。
    • [[MinuteSecondSeparator]] 必须是一个 String 值,表示在使用 "numeric""2-digit" 样式时,对于该 locale 与编号系统组合,在分钟和秒之间使用的适当分隔符。
    • [[TwoDigitHours]] 必须是一个 Boolean 值,指示使用 "numeric" 样式时小时是否始终以两位数字显示。
Note
建议实现使用 Common Locale Data Repository 提供的 locale 数据(可在 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 ( )

该函数提供对对象初始化期间计算出的 locale 和选项的访问。

  1. dfthis 值。
  2. 执行 ? RequireInternalSlot(df, [[InitializedDurationFormat]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. Table 21 的每一行(表头行除外),按表格顺序,执行
    1. propertyKey 为当前行的 Property 值。
    2. valuedf 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 如果 value 不是 undefined,则
      1. 如果当前行中存在 Conversion 值,则令 conversion 为该值;否则令 conversionempty
      2. 如果 conversionnumber,则
        1. value 设置为 𝔽(value)。
      3. 否则如果 conversion 不是 empty,则
        1. 断言:conversionstyle+displayvalueDuration Unit Options Record
        2. 注:value.[[Style]] 将以名为 propertyKey 的属性表示(一个复数 Temporal 单位),随后 value.[[Display]] 将以名称为 propertyKey 后缀加上 "Display" 的属性表示。
        3. stylevalue.[[Style]]
        4. 如果 style"fractional",则
          1. 断言:IsFractionalSecondUnitName(propertyKey) 是 true
          2. style 设置为 "numeric"
        5. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, style)。
        6. propertyKey 设置为 propertyKey"Display" 的字符串拼接。
        7. value 设置为 value.[[Display]]
      4. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  5. 返回 options
Table 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 )

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

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

13.3.4 Intl.DurationFormat.prototype.formatToParts ( duration )

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

  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% 属性的初始值是 String 值 "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 Records

Duration Record 是用于表示 Duration 的 Record 值。

Duration Records 具有 Table 22 中列出的字段

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

13.5.2 ToIntegerIfIntegral ( arg )

The abstract operation ToIntegerIfIntegral takes argument arg (一个 ECMAScript 语言值) and returns 要么是包含一个整数的正常完成,要么是一个抛出完成. 它将 arg 转换为表示其 Number 值的整数,或者在该值不是整数时抛出一个 RangeError。 It performs the following steps when called:

  1. number 为 ? ToNumber(arg)。
  2. 如果 number 不是一个 integral Number,则抛出一个 RangeError 异常。
  3. 返回 (number)。

13.5.3 ToDurationRecord ( input )

The abstract operation ToDurationRecord takes argument input (一个 ECMAScript 语言值) and returns 要么是包含一个 Duration Record 的正常完成,要么是一个抛出完成. 它将表示 Duration 的给定对象转换为 Duration Record。 It performs the following steps when called:

  1. 如果 input 不是一个 Object,则
    1. 如果 input 是一个 String,则抛出一个 RangeError 异常。
    2. 抛出一个 TypeError 异常。
  2. result 为一个新的 Duration Record,其每个字段都设置为 0。
  3. days 为 ? Get(input, "days")。
  4. 如果 days 不是 undefined,则将 result.[[Days]] 设置为 ? ToIntegerIfIntegral(days)。
  5. hours 为 ? Get(input, "hours")。
  6. 如果 hours 不是 undefined,则将 result.[[Hours]] 设置为 ? ToIntegerIfIntegral(hours)。
  7. microseconds 为 ? Get(input, "microseconds")。
  8. 如果 microseconds 不是 undefined,则将 result.[[Microseconds]] 设置为 ? ToIntegerIfIntegral(microseconds)。
  9. milliseconds 为 ? Get(input, "milliseconds")。
  10. 如果 milliseconds 不是 undefined,则将 result.[[Milliseconds]] 设置为 ? ToIntegerIfIntegral(milliseconds)。
  11. minutes 为 ? Get(input, "minutes")。
  12. 如果 minutes 不是 undefined,则将 result.[[Minutes]] 设置为 ? ToIntegerIfIntegral(minutes)。
  13. months 为 ? Get(input, "months")。
  14. 如果 months 不是 undefined,则将 result.[[Months]] 设置为 ? ToIntegerIfIntegral(months)。
  15. nanoseconds 为 ? Get(input, "nanoseconds")。
  16. 如果 nanoseconds 不是 undefined,则将 result.[[Nanoseconds]] 设置为 ? ToIntegerIfIntegral(nanoseconds)。
  17. seconds 为 ? Get(input, "seconds")。
  18. 如果 seconds 不是 undefined,则将 result.[[Seconds]] 设置为 ? ToIntegerIfIntegral(seconds)。
  19. weeks 为 ? Get(input, "weeks")。
  20. 如果 weeks 不是 undefined,则将 result.[[Weeks]] 设置为 ? ToIntegerIfIntegral(weeks)。
  21. years 为 ? Get(input, "years")。
  22. 如果 years 不是 undefined,则将 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 )

The abstract operation DurationSign takes argument duration (一个 Duration Record) and returns -1、0 或 1. 如果 duration 实参中最高有效的非零字段为正,则返回 1;如果最高有效的非零字段为负,则返回 -1。如果 duration 的所有字段都是零,则返回 0。 It performs the following steps when called:

  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 )

The abstract operation IsValidDuration takes arguments years (一个整数), months (一个整数), weeks (一个整数), days (一个整数), hours (一个整数), minutes (一个整数), seconds (一个整数), milliseconds (一个整数), microseconds (一个整数), and nanoseconds (一个整数) and returns 一个 Boolean. 如果其实参构成可用于构造 Duration Record 的有效输入,则返回 true;否则返回 false。 It performs the following steps when called:

  1. sign 为 0。
  2. 对 « years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds » 的每个值 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 )

The abstract operation GetDurationUnitOptions takes arguments unit (一个 String), options (一个 Object), baseStyle (一个 String), stylesList (一个 Strings 的 List), digitalBase (一个 String), prevStyle (一个 String), and twoDigitHours (一个 Boolean) and returns 要么是包含一个 Duration Unit Options Record 的正常完成,要么是一个抛出完成. 它从 Object 中提取给定 unit 的相关选项,并以 Record 形式返回。 It performs the following steps when called:

  1. style 为 ? GetOption(options, unit, string, stylesList, undefined)。
  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. displayFieldunit"Display" 的字符串拼接。
  6. display 为 ? GetOption(options, displayField, string, « "auto", "always" », displayDefault)。
  7. 执行 ? ValidateDurationUnitStyle(unit, style, display, prevStyle)。
  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 Records

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

Table 23: Duration Unit Options Record
字段名称 值类型
[[Style]] 来自 Table 20 的 Styles 列的一个 String
[[Display]] "auto""always"

13.5.6.2 ValidateDurationUnitStyle ( unit, style, display, prevStyle )

The abstract operation ValidateDurationUnitStyle takes arguments unit (一个 String), style (一个 String), display (一个 String), and prevStyle (一个 String) and returns 要么是包含 unused 的正常完成,要么是一个抛出完成. It performs the following steps when called:

  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
Note
前述算法中未引用 unit,但建议实现构造所抛出异常的消息时使用它。

13.5.7 ComputeFractionalDigits ( durationFormat, duration )

The abstract operation ComputeFractionalDigits takes arguments durationFormat (一个 DurationFormat Object) and duration (一个 Duration Record) and returns 一个数学值. 它计算 durationFormat 中所有使用 "fractional" 样式的单位的值之和,并将其表示为 durationFormat 中不使用 "fractional" 样式的最小单位的分数。 It performs the following steps when called:

  1. result 为 0。
  2. exponent 为 3。
  3. Table 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 )

The abstract operation NextUnitFractional takes arguments durationFormat (一个 DurationFormat Object) and unit (一个 String) and returns 一个 Boolean. 如果下一个更小的单位使用 "fractional" 样式,则返回 true。 It performs the following steps when called:

  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 )

The abstract operation FormatNumericHours takes arguments durationFormat (一个 DurationFormat object), hoursValue (一个整数), and signDisplayed (一个 Boolean) and returns 一个 RecordsList. hoursValue 是一个表示小时数的整数。它根据 durationFormat 的有效 locale 和格式化选项,为 hoursValue 创建各个部分。 It performs the following steps when called:

  1. result 为一个新的空 List
  2. hoursStyledurationFormat.[[HoursOptions]].[[Style]]
  3. 断言:hoursStyle"numeric"hoursStyle"2-digit"
  4. nfOptionsOrdinaryObjectCreate(null)。
  5. numberingSystemdurationFormat.[[NumberingSystem]]
  6. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", numberingSystem)。
  7. 如果 hoursStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumIntegerDigits", 2𝔽)。
  8. 如果 signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "signDisplay", "never")。
  9. 执行 ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false)。
  10. nf 为 ! Construct(%Intl.NumberFormat%, « durationFormat.[[Locale]], nfOptions »)。
  11. hoursPartsPartitionNumberPattern(nf, hoursValue)。
  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 )

The abstract operation FormatNumericMinutes takes arguments durationFormat (一个 DurationFormat Object), minutesValue (一个整数), hoursDisplayed (一个 Boolean), and signDisplayed (一个 Boolean) and returns 一个 RecordsList. minutesValue 是一个表示分钟数的整数。它根据 durationFormat 的有效 locale 和格式化选项,为 minutesValue 创建各个部分。 It performs the following steps when called:

  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. nfOptionsOrdinaryObjectCreate(null)。
  6. numberingSystemdurationFormat.[[NumberingSystem]]
  7. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", numberingSystem)。
  8. 如果 minutesStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumIntegerDigits", 2𝔽)。
  9. 如果 signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "signDisplay", "never")。
  10. 执行 ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false)。
  11. nf 为 ! Construct(%Intl.NumberFormat%, « durationFormat.[[Locale]], nfOptions »)。
  12. minutesPartsPartitionNumberPattern(nf, minutesValue)。
  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 )

The abstract operation FormatNumericSeconds takes arguments durationFormat (一个 DurationFormat Object), secondsValue (一个数学值), minutesDisplayed (一个 Boolean), and signDisplayed (一个 Boolean) and returns 一个 RecordsList. secondsValue 是一个表示秒数的数学值。它根据 durationFormat 的有效 locale 和格式化选项,为 secondsValue 创建各个部分。 It performs the following steps when called:

  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. nfOptionsOrdinaryObjectCreate(null)。
  6. numberingSystemdurationFormat.[[NumberingSystem]]
  7. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", numberingSystem)。
  8. 如果 secondsStyle"2-digit",则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumIntegerDigits", 2𝔽)。
  9. 如果 signDisplayedfalse,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "signDisplay", "never")。
  10. 执行 ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false)。
  11. fractionDigitsdurationFormat.[[FractionalDigits]]
  12. 如果 fractionDigitsundefined,则
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "maximumFractionDigits", 9𝔽)。
    2. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumFractionDigits", +0𝔽)。
  13. 否则,
    1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "maximumFractionDigits", fractionDigits)。
    2. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumFractionDigits", fractionDigits)。
  14. 执行 ! CreateDataPropertyOrThrow(nfOptions, "roundingMode", "trunc")。
  15. nf 为 ! Construct(%Intl.NumberFormat%, « durationFormat.[[Locale]], nfOptions »)。
  16. secondsPartsPartitionNumberPattern(nf, secondsValue)。
  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 )

The abstract operation FormatNumericUnits takes arguments durationFormat (一个 DurationFormat Object), duration (一个 Duration Record), firstNumericUnit (一个 String), and signDisplayed (一个 Boolean) and returns 一个 RecordsList. 它根据 durationFormat 的有效 locale 和格式化选项,创建表示 duration 中使用 "numeric""2-digit" 样式的元素的各个部分。 It performs the following steps when called:

  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(durationFormat, duration)。
  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(durationFormat, hoursValue, signDisplayed)。
    3. numericPartsList 设置为 numericPartsListhoursParts 的列表拼接。
    4. signDisplayed 设置为 false
  17. 如果 minutesFormattedtrue,则
    1. 如果 signDisplayedtrue,则
      1. 如果 minutesValue 是 0 且 DurationSign(duration) 是 -1,则
        1. minutesValue 设置为 negative-zero
    2. minutesPartsFormatNumericMinutes(durationFormat, minutesValue, hoursFormatted, signDisplayed)。
    3. numericPartsList 设置为 numericPartsListminutesParts 的列表拼接。
    4. signDisplayed 设置为 false
  18. 如果 secondsFormattedtrue,则
    1. secondsPartsFormatNumericSeconds(durationFormat, secondsValue, minutesFormatted, signDisplayed)。
    2. numericPartsList 设置为 numericPartsListsecondsParts 的列表拼接。
  19. 返回 numericPartsList

13.5.13 IsFractionalSecondUnitName ( unit )

The abstract operation IsFractionalSecondUnitName takes argument unit (一个 String) and returns 一个 Boolean. It performs the following steps when called:

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

13.5.14 ListFormatParts ( durationFormat, partitionedPartsList )

The abstract operation ListFormatParts takes arguments durationFormat (一个 DurationFormat Object) and partitionedPartsList (一个 Lists of RecordsList) and returns 一个 List. 它根据 durationFormat 的有效 locale 和格式化选项,创建一个对应于 partitionedPartsList 中各个 List 内各部分的 List。 It performs the following steps when called:

  1. lfOptionsOrdinaryObjectCreate(null)。
  2. 执行 ! CreateDataPropertyOrThrow(lfOptions, "type", "unit")。
  3. listStyledurationFormat.[[Style]]
  4. 如果 listStyle"digital",则
    1. listStyle 设为 "short"
  5. 执行 ! CreateDataPropertyOrThrow(lfOptions, "style", listStyle)。
  6. lf 为 ! Construct(%Intl.ListFormat%, « durationFormat.[[Locale]], lfOptions »)。
  7. strings 为一个新的空 List
  8. partitionedPartsList 的每个元素 parts,执行
    1. string 为空 String。
    2. parts 的每个 Record { [[Type]], [[Value]], [[Unit]] } part,执行
      1. string 设为 stringpart.[[Value]] 的字符串连接。
    3. string 追加到 strings
  9. formattedPartsListCreatePartsFromList(lf, strings)。
  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 )

The abstract operation PartitionDurationFormatPattern takes arguments durationFormat (一个 DurationFormat) and duration (一个 Duration Record) and returns 一个 List. 它根据 durationFormat 的有效 locale 和格式化选项,为 duration 创建对应的各个部分。 It performs the following steps when called:

  1. result 为一个新的空 List
  2. signDisplayedtrue
  3. numericUnitFoundfalse
  4. numericUnitFoundfalse 时,重复按表格顺序遍历 Table 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(durationFormat, duration, unit, signDisplayed)。
      2. 如果 numericPartsList 不是空,则将 numericPartsList 追加到 result
      3. numericUnitFound 设置为 true
    8. 否则,
      1. nfOptionsOrdinaryObjectCreate(null)。
      2. 如果 NextUnitFractional(durationFormat, unit) 是 true,则
        1. value 设置为 value + ComputeFractionalDigits(durationFormat, duration)。
        2. fractionDigitsdurationFormat.[[FractionalDigits]]
        3. 如果 fractionDigitsundefined,则
          1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "maximumFractionDigits", 9𝔽)。
          2. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumFractionDigits", +0𝔽)。
        4. 否则,
          1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "maximumFractionDigits", fractionDigits)。
          2. 执行 ! CreateDataPropertyOrThrow(nfOptions, "minimumFractionDigits", fractionDigits)。
        5. 执行 ! CreateDataPropertyOrThrow(nfOptions, "roundingMode", "trunc")。
        6. numericUnitFound 设置为 true
      3. 如果 display"always"value 不是 0,则
        1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "numberingSystem", durationFormat.[[NumberingSystem]])。
        2. 如果 signDisplayedtrue,则
          1. signDisplayed 设置为 false
          2. 如果 value 是 0 且 DurationSign(duration) 是 -1,则将 value 设置为 negative-zero
        3. 否则,
          1. 执行 ! CreateDataPropertyOrThrow(nfOptions, "signDisplay", "never")。
        4. 执行 ! CreateDataPropertyOrThrow(nfOptions, "style", "unit")。
        5. 执行 ! CreateDataPropertyOrThrow(nfOptions, "unit", numberFormatUnit)。
        6. 执行 ! CreateDataPropertyOrThrow(nfOptions, "unitDisplay", style)。
        7. nf 为 ! Construct(%Intl.NumberFormat%, « durationFormat.[[Locale]], nfOptions »)。
        8. partsPartitionNumberPattern(nf, value)。
        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(durationFormat, result)。
Table 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 ] ] )

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

  1. 如果 NewTarget 是 undefined,则抛出一个 TypeError 异常。
  2. listFormat 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.ListFormat.prototype%", « [[InitializedListFormat]], [[Locale]], [[Type]], [[Style]], [[Templates]] »)。
  3. optionsResolution 为 ? ResolveOptions(%Intl.ListFormat%, %Intl.ListFormat%.[[LocaleData]], locales, options)。
  4. options 设置为 optionsResolution.[[Options]]
  5. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  6. listFormat.[[Locale]] 设置为 resolvedLocale.[[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. resolvedLocaleDataresolvedLocale.[[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 ] )

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

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

14.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 中描述的约束范围内由实现定义。

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

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

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

[[LocaleData]] 内部槽的值在 9.1 中描述的约束范围内由实现定义,并且对于 %Intl.ListFormat%.[[AvailableLocales]] 中的每个 locale 值 locale,满足以下额外约束:

  • [[LocaleData]].[[<locale>]] 是一个 Record,它具有三个字段 [[conjunction]][[disjunction]][[unit]]。其中每个字段都是一个 Record,该 Record 必须具有名称为三种格式化样式的字段:[[long]][[short]][[narrow]]
  • 这些字段中的每一个都被视为一个 ListFormat 模板集,它必须是一个 RecordsList,且这些 Record 具有命名字段:[[Pair]][[Start]][[Middle]][[End]]。这些字段中的每一个都必须是 LDML List Format Rules 中规定的模板字符串。每个模板字符串都必须恰好包含一次子字符串 "{0}""{1}"。子字符串 "{0}" 应出现在子字符串 "{1}" 之前。
Note 2
建议实现使用 Common Locale Data Repository 提供的 locale 数据(可在 https://cldr.unicode.org/ 获取)。在 LDML 的 listPattern 中,conjunction 对应于 "standard",disjunction 对应于 "or",unit 对应于 "unit"。
Note 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 ( )

该函数提供对对象初始化期间计算出的 locale 和选项的访问。

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

14.3.3 Intl.ListFormat.prototype.format ( list )

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

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

14.3.4 Intl.ListFormat.prototype.formatToParts ( list )

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

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

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

%Symbol.toStringTag% 属性的初始值是 String 值 "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]] 是一个 String 值,带有列表格式化样式使用的本地化的 locale 的语言标签
  • [[Type]] 是 String 值 "conjunction""disjunction""unit" 之一,用于标识所使用的类型列表。
  • [[Style]] 是 String 值 "long""short""narrow" 之一,用于标识所使用的列表格式化样式。
  • [[Templates]] 是一个 ListFormat 模板集

14.5 ListFormat 对象的抽象操作

14.5.1 DeconstructPattern ( pattern, placeables )

The abstract operation DeconstructPattern takes arguments pattern (一个 Pattern String) and placeables (一个 Record) and returns 一个 List.

它将 pattern 字符串拆解为一个 parts 的 List

placeables 是一个 Record,其键是 pattern 字符串中使用的 placeables 标记,值是 parts Record(如来自 PartitionPatternRecord),这些值将在结果 List 中用于表示该标记部分。 示例:

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

输出(parts Records 的 List):
  «
    {[[Type]]: "literal", [[Value]]: "AA"},
    {[[Type]]: "hour", [[Value]]: "15"},
    {[[Type]]: "literal", [[Value]]: "BB"},
    {[[Type]]: "minute", [[Value]]: "06"},
    {[[Type]]: "literal", [[Value]]: "CC"}
  »
          

It performs the following steps when called:

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

14.5.2 CreatePartsFromList ( listFormat, list )

The abstract operation CreatePartsFromList takes arguments listFormat (一个 Intl.ListFormat) and list (一个 Strings 的 List) and returns 一个 RecordsList,每个 Record 带有字段 [[Type]]"element""literal")和 [[Value]](一个 String). 它根据 listFormat 的有效 locale 和格式化选项,创建对应的 parts 的 List。 It performs the following steps when called:

  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(pattern, placeables)。
  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.[[Locale]]headpartslistFormat.[[Templates]] 中由实现定义的索引。
    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(pattern, placeables)。
    8. i 设为 i - 1。
  8. 返回 parts
Note
用于在多个模板之间选择的索引 n 允许 conjunction 依赖上下文,例如在西班牙语中,可以根据后面的词选择 "y" 或 "e"。

14.5.3 FormatList ( listFormat, list )

The abstract operation FormatList takes arguments listFormat (一个 Intl.ListFormat) and list (一个 Strings 的 List) and returns 一个 String. It performs the following steps when called:

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

14.5.4 FormatListToParts ( listFormat, list )

The abstract operation FormatListToParts takes arguments listFormat (一个 Intl.ListFormat) and list (一个 Strings 的 List) and returns 一个 Array. It performs the following steps when called:

  1. partsCreatePartsFromList(listFormat, list)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]] } part,执行
    1. objOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(obj, "type", part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(obj, "value", part.[[Value]])。
    4. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), obj)。
    5. n 设为 n + 1。
  5. 返回 result

14.5.5 StringListFromIterable ( iterable )

The abstract operation StringListFromIterable takes argument iterable (一个 ECMAScript 语言值) and returns 要么是包含一个 Strings 的 List 的正常完成,要么是一个抛出完成. It performs the following steps when called:

  1. 如果 iterableundefined,则
    1. 返回一个新的空 List
  2. iteratorRecord 为 ? GetIterator(iterable, sync)。
  3. list 为一个新的空 List
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,则
      1. 返回 list
    3. 如果 next 不是一个 String,则
      1. errorThrowCompletion(一个新创建的 TypeError 对象)。
      2. 返回 ? IteratorClose(iteratorRecord, error)。
    4. next 追加到 list
Note

该算法在遇到不是 String 的值时引发异常,因为对于任意值并不存在明显的 locale 感知强制转换。

15 Locale 对象

15.1 Intl.Locale 构造函数

Intl.Locale 构造函数:

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

15.1.1 Intl.Locale ( tag [ , options ] )

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

  1. 如果 NewTarget 是 undefined,则抛出一个 TypeError 异常。
  2. localeExtensionKeys%Intl.Locale%.[[LocaleExtensionKeys]]
  3. internalSlotsList 为 « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[FirstDayOfWeek]], [[HourCycle]], [[NumberingSystem]] »。
  4. 如果 localeExtensionKeys 包含 "kf",则
    1. [[CaseFirst]] 追加到 internalSlotsList
  5. 如果 localeExtensionKeys 包含 "kn",则
    1. [[Numeric]] 追加到 internalSlotsList
  6. locale 为 ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.Locale.prototype%", internalSlotsList)。
  7. 如果 tag 不是 String 且 tag 不是 Object,则抛出一个 TypeError 异常。
  8. 如果 tag 是 Object 且 tag 具有 [[InitializedLocale]] 内部槽,则
    1. tag 设为 tag.[[Locale]]
  9. 否则,
    1. tag 设为 ? ToString(tag)。
  10. options 设为 ? CoerceOptionsToObject(options)。
  11. 如果 IsWellFormedLanguageTag(tag) 是 false,则抛出一个 RangeError 异常。
  12. 注:因为LanguageId 规范化可以根据 supplementalMetadata.xml 中的别名规则以任意方式改变 tag,所以有必要在应用 options 的覆盖之前执行此类规范化。
  13. tag 设为 CanonicalizeUnicodeLocaleId(tag)。
  14. tag 设为 ? UpdateLanguageId(tag, options)。
  15. opt 为一个新的 Record
  16. calendar 为 ? GetOption(options, "calendar", string, empty, undefined)。
  17. 如果 calendar 不是 undefined,则
    1. 如果 calendar 不能由 type Unicode 语言环境非终结符匹配,则抛出一个 RangeError 异常。
  18. opt.[[ca]] 设为 calendar
  19. collation 为 ? GetOption(options, "collation", string, empty, undefined)。
  20. 如果 collation 不是 undefined,则
    1. 如果 collation 不能由 type Unicode 语言环境非终结符匹配,则抛出一个 RangeError 异常。
  21. opt.[[co]] 设为 collation
  22. fw 为 ? GetOption(options, "firstDayOfWeek", string, empty, undefined)。
  23. 如果 fw 不是 undefined,则
    1. fw 设为 WeekdayToUValue(fw)。
    2. 如果 fw 不能由 type Unicode 语言环境非终结符匹配,则抛出一个 RangeError 异常。
  24. opt.[[fw]] 设为 fw
  25. hc 为 ? GetOption(options, "hourCycle", string, « "h11", "h12", "h23", "h24" », undefined)。
  26. opt.[[hc]] 设为 hc
  27. kf 为 ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined)。
  28. opt.[[kf]] 设为 kf
  29. kn 为 ? GetOption(options, "numeric", boolean, empty, undefined)。
  30. 如果 kn 不是 undefined,则将 kn 设为 ! ToString(kn)。
  31. opt.[[kn]] 设为 kn
  32. numberingSystem 为 ? GetOption(options, "numberingSystem", string, empty, undefined)。
  33. 如果 numberingSystem 不是 undefined,则
    1. 如果 numberingSystem 不能由 type Unicode 语言环境非终结符匹配,则抛出一个 RangeError 异常。
  34. opt.[[nu]] 设为 numberingSystem
  35. localeRecordMakeLocaleRecord(tag, opt, localeExtensionKeys)。
  36. locale.[[Locale]] 设为 localeRecord.[[locale]]
  37. locale.[[Calendar]] 设为 localeRecord.[[ca]]
  38. locale.[[Collation]] 设为 localeRecord.[[co]]
  39. locale.[[FirstDayOfWeek]] 设为 localeRecord.[[fw]]
  40. locale.[[HourCycle]] 设为 localeRecord.[[hc]]
  41. 如果 localeExtensionKeys 包含 "kf",则
    1. locale.[[CaseFirst]] 设为 localeRecord.[[kf]]
  42. 如果 localeExtensionKeys 包含 "kn",则
    1. 如果 localeRecord.[[kn]]"true" 或空 String,则
      1. locale.[[Numeric]] 设为 true
    2. 否则,
      1. locale.[[Numeric]] 设为 false
  43. locale.[[NumberingSystem]] 设为 localeRecord.[[nu]]
  44. 返回 locale

15.1.2 UpdateLanguageId ( tag, options )

The abstract operation UpdateLanguageId takes arguments tag (一个格式良好的语言标签) and options (一个 Object) and returns 要么是包含一个格式良好的语言标签的正常完成,要么是一个抛出完成. 它从 options 的对应属性更新 tag 中的 unicode_language_id 子标签,对其进行验证,并返回结果。 It performs the following steps when called:

  1. baseNameGetLocaleBaseName(tag)。
  2. language 为 ? GetOption(options, "language", string, empty, GetLocaleLanguage(baseName))。
  3. 如果 language 不能由 unicode_language_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
  4. script 为 ? GetOption(options, "script", string, empty, GetLocaleScript(baseName))。
  5. 如果 script 不是 undefined,则
    1. 如果 script 不能由 unicode_script_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
  6. region 为 ? GetOption(options, "region", string, empty, GetLocaleRegion(baseName))。
  7. 如果 region 不是 undefined,则
    1. 如果 region 不能由 unicode_region_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
  8. variants 为 ? GetOption(options, "variants", string, empty, GetLocaleVariants(baseName))。
  9. 如果 variants 不是 undefined,则
    1. 如果 variants 是空 String,则抛出一个 RangeError 异常。
    2. lowerVariantsvariants 的 ASCII 小写形式。
    3. variantSubtagsStringSplitToList(lowerVariants, "-")。
    4. variantSubtags 的每个元素 variant,执行
      1. 如果 variant 不能由 unicode_variant_subtag Unicode locale 非终结符匹配,则抛出一个 RangeError 异常。
    5. 如果 variantSubtags 包含任何重复元素,则抛出一个 RangeError 异常。
  10. allExtensionstag 中跟在 baseName 之后的后缀。
  11. newTaglanguage
  12. 如果 script 不是 undefined,则将 newTag 设置为 newTag"-"script 的字符串拼接。
  13. 如果 region 不是 undefined,则将 newTag 设置为 newTag"-"region 的字符串拼接。
  14. 如果 variants 不是 undefined,则将 newTag 设置为 newTag"-"variants 的字符串拼接。
  15. newTag 设置为 newTagallExtensions 的字符串拼接。
  16. 返回 newTag

15.1.3 MakeLocaleRecord ( tag, options, localeExtensionKeys )

The abstract operation MakeLocaleRecord takes arguments tag (一个语言标签), options (一个 Record), and localeExtensionKeys (一个 Strings 的 List) and returns 一个 Record. 它构造并返回一个 Record,其中 localeExtensionKeys 的每个元素都定义一个对应字段,该字段包含 tag 的任何 Unicode locale 扩展序列中的数据,并由 options 的对应字段覆盖;此外还包含一个 [[locale]] 字段,其中包含将这些字段并入 tag 后得到的 Unicode 规范化 locale 标识符。 It performs the following steps when called:

  1. 如果 tag 包含一个作为 Unicode locale 扩展序列substring,则
    1. extension 为由 tagUnicode locale 扩展序列substring 组成的 String 值。
    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. 如果 overrideValue 不是 undefined,则
      1. value 设置为 CanonicalizeUValue(key, overrideValue)。
      2. 如果 entry 不是 empty,则
        1. entry.[[Value]] 设置为 value
      3. 否则,
        1. Record { [[Key]]: key, [[Value]]: value } 追加到 keywords
    6. result.[[<key>]] 设置为 value
  5. locale 为移除任何 Unicode locale 扩展序列后的 tag 的 String 值。
  6. 如果 attributes 不是空,或 keywords 不是空,则
    1. result.[[locale]] 设置为 InsertUnicodeExtensionAndCanonicalize(locale, attributes, keywords)。
  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", "fw", "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 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.3 get Intl.Locale.prototype.calendar

Intl.Locale.prototype.calendar 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

  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 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.5 get Intl.Locale.prototype.collation

Intl.Locale.prototype.collation 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.6 get Intl.Locale.prototype.firstDayOfWeek

Intl.Locale.prototype.firstDayOfWeek 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.7 get Intl.Locale.prototype.hourCycle

Intl.Locale.prototype.hourCycle 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.8 get Intl.Locale.prototype.language

Intl.Locale.prototype.language 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.9 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.10 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.11 get Intl.Locale.prototype.numberingSystem

Intl.Locale.prototype.numberingSystem 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.12 get Intl.Locale.prototype.numeric

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

Intl.Locale.prototype.numeric 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.13 get Intl.Locale.prototype.region

Intl.Locale.prototype.region 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.14 get Intl.Locale.prototype.script

Intl.Locale.prototype.script 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

15.3.15 Intl.Locale.prototype.toString ( )

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

15.3.16 Intl.Locale.prototype.getCalendars ( )

getCalendars 方法被调用时,执行以下步骤:

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

15.3.17 Intl.Locale.prototype.getCollations ( )

getCollations 方法被调用时,执行以下步骤:

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

15.3.18 Intl.Locale.prototype.getHourCycles ( )

getHourCycles 方法被调用时,执行以下步骤:

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

15.3.19 Intl.Locale.prototype.getNumberingSystems ( )

getNumberingSystems 方法被调用时,执行以下步骤:

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

15.3.20 Intl.Locale.prototype.getTimeZones ( )

getTimeZones 方法被调用时,执行以下步骤:

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

15.3.21 Intl.Locale.prototype.getTextInfo ( )

getTextInfo 方法被调用时,执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc, [[InitializedLocale]])。
  3. infoOrdinaryObjectCreate(%Object.prototype%)。
  4. dirTextDirectionOfLocale(loc)。
  5. 执行 ! CreateDataPropertyOrThrow(info, "direction", dir)。
  6. 返回 info

15.3.22 Intl.Locale.prototype.getWeekInfo ( )

getWeekInfo 方法被调用时,执行以下步骤:

  1. locthis 值。
  2. 执行 ? RequireInternalSlot(loc, [[InitializedLocale]])。
  3. infoOrdinaryObjectCreate(%Object.prototype%)。
  4. weekInfoWeekInfoOfLocale(loc)。
  5. 执行 ! CreateDataPropertyOrThrow(info, "firstDay", weekInfo.[[FirstDay]])。
  6. 执行 ! CreateDataPropertyOrThrow(info, "weekend", CreateArrayFromList(weekInfo.[[Weekend]]))。
  7. 返回 info

15.3.23 get Intl.Locale.prototype.variants

Intl.Locale.prototype.variants 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

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

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

%Symbol.toStringTag% 属性的初始值是 String 值 "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]] 是一个 String 值,带有其本地化用于格式化的 locale 的语言标签
  • [[Calendar]] 要么是 undefined,要么是一个规范形式的格式良好的 Unicode Calendar Identifier String 值。
  • [[Collation]] 要么是 undefined,要么是一个规范形式的格式良好的 Unicode Collation Identifier String 值。
  • [[FirstDayOfWeek]] 要么是 undefined,要么是一个规范形式的有效 Unicode First Day Identifier String 值。
  • [[HourCycle]] 要么是 undefined,要么是一个规范形式的有效 Unicode Hour Cycle Identifier String 值。
  • [[NumberingSystem]] 要么是 undefined,要么是一个规范形式的格式良好的 Unicode Number System Identifier String 值。
  • [[CaseFirst]] 要么是 undefined,要么是 String 值 "upper""lower""false" 之一。仅当 %Intl.Locale%[[LocaleExtensionKeys]] 内部槽包含 "kf" 时,此内部槽才存在。
  • [[Numeric]] 要么是 undefined,要么是一个 Boolean 值,指定该 locale 是否使用数字排序。仅当 %Intl.Locale%[[LocaleExtensionKeys]] 内部槽包含 "kn" 时,此内部槽才存在。

15.5 Locale 对象的抽象操作

15.5.1 GetLocaleBaseName ( locale )

The abstract operation GetLocaleBaseName takes argument locale (一个 String) and returns 一个 String. It performs the following steps when called:

  1. 断言:locale 可由 unicode_locale_id Unicode locale 非终结符匹配。
  2. 返回 locale 中由 unicode_language_id Unicode locale 非终结符匹配的最长前缀。

15.5.2 GetLocaleLanguage ( locale )

The abstract operation GetLocaleLanguage takes argument locale (一个 String) and returns 一个 String. It performs the following steps when called:

  1. baseNameGetLocaleBaseName(locale)。
  2. 断言:baseName 的第一个子标签可由 unicode_language_subtag Unicode locale 非终结符匹配。
  3. 返回 baseName 的第一个子标签

15.5.3 GetLocaleScript ( locale )

The abstract operation GetLocaleScript takes argument locale (一个 String) and returns 一个 String 或 undefined. It performs the following steps when called:

  1. baseNameGetLocaleBaseName(locale)。
  2. 断言:baseName 至多包含一个可由 unicode_script_subtag Unicode locale 非终结符匹配的子标签
  3. 如果 baseName 包含一个由 unicode_script_subtag Unicode locale 非终结符匹配的子标签,则返回该子标签
  4. 返回 undefined

15.5.4 GetLocaleRegion ( locale )

The abstract operation GetLocaleRegion takes argument locale (一个 String) and returns 一个 String 或 undefined. It performs the following steps when called:

  1. baseNameGetLocaleBaseName(locale)。
  2. 注:unicode_region_subtag 子标签仅在紧跟初始 unicode_language_subtag 子标签之后的位置有效,它们之间可选地有一个 unicode_script_subtag 子标签。在该位置,unicode_region_subtag 不会与任何其他有效子标签混淆,因为它们的产生式互不相交。
  3. 断言:baseName 的第一个子标签可由 unicode_language_subtag Unicode locale 非终结符匹配。
  4. baseNameTailbaseName 中跟在第一个子标签之后的后缀。
  5. 断言:baseNameTail 至多包含一个可由 unicode_region_subtag Unicode locale 非终结符匹配的子标签
  6. 如果 baseNameTail 包含一个由 unicode_region_subtag Unicode locale 非终结符匹配的子标签,则返回该子标签
  7. 返回 undefined

15.5.5 GetLocaleVariants ( locale )

The abstract operation GetLocaleVariants takes argument locale (一个 String) and returns 一个 String 或 undefined. It performs the following steps when called:

  1. baseNameGetLocaleBaseName(locale)。
  2. 注:baseName 中每个前面带有 "-"子标签都是 unicode_script_subtagunicode_region_subtagunicode_variant_subtag,但任何由 unicode_variant_subtag 匹配的子字符串都严格长于其任何也可由其他产生式之一匹配的前缀。
  3. subtagsStringSplitToList(baseName, "-")。
  4. dashIndexsubtags[0] 的长度。
  5. subtags 中移除第一个元素。
  6. subtags 的每个字符串 subtag,执行
    1. 如果 subtagunicode_variant_subtag Unicode 语言环境非终结符匹配,则
      1. 返回从 dashIndex + 1 开始的 baseName 子字符串。
    2. subtagLengthsubtag 的长度。
    3. dashIndex 设为 dashIndex + subtagLength + 1。
  7. 返回 undefined

15.5.6 UnicodeExtensionValue ( locale, key )

The abstract operation UnicodeExtensionValue takes arguments locale (一个 Unicode 规范化 locale 标识符) and key (一个 String) and returns 一个 String 或 empty. It performs the following steps when called:

  1. 如果 locale 包含一个 Unicode locale 扩展序列,则
    1. extensionlocaleUnicode locale 扩展序列
    2. componentsUnicodeExtensionComponents(extension)。
    3. keywordscomponents.[[Keywords]]
    4. 如果存在 keywords 的元素 entry,使得 entry.[[Key]]key,则返回 entry.[[Value]]
  2. 返回 empty

15.5.7 CanonicalUnicodeSubdivision ( locale, key )

The abstract operation CanonicalUnicodeSubdivision takes arguments locale (一个 Unicode 规范化 locale 标识符) and key ("rg""sd") and returns 一个 String 或 undefined. It performs the following steps when called:

  1. subdivisionUnicodeExtensionValue(locale, key)。
  2. 如果 subdivisionempty,则返回 undefined
  3. 如果 subdivision 不能由 unicode_subdivision_id Unicode locale 非终结符匹配,则返回 undefined
  4. regionsubdivision 中由 unicode_region_subtag Unicode locale 非终结符匹配的最长前缀。
  5. regionLocale"und-"region 的字符串拼接。
  6. regionLocale 设置为 CanonicalizeUnicodeLocaleId(regionLocale)。
  7. 返回 GetLocaleRegion(regionLocale)。

15.5.8 RegionPreference ( locale )

The abstract operation RegionPreference takes argument locale (一个 Unicode 规范化 locale 标识符) and returns 一个带有字段 [[Region]](一个 String)和 [[RegionOverride]](一个 String 或 undefined)的 Record. It performs the following steps when called:

  1. regionGetLocaleRegion(locale)。
  2. 如果 regionundefined,则
    1. region 设置为 CanonicalUnicodeSubdivision(locale, "sd")。
    2. 如果 regionundefined,则
      1. maximal 为将 Add Likely Subtags 算法应用于 locale 的结果。如果发出错误信号,则将 maximal 设置为 locale
      2. maximal 设置为 CanonicalizeUnicodeLocaleId(maximal)。
      3. region 设置为 GetLocaleRegion(maximal)。
      4. 如果 regionundefined,则
        1. region 设置为 "001"
  3. regionOverrideCanonicalUnicodeSubdivision(locale, "rg")。
  4. 返回 { [[Region]]: region, [[RegionOverride]]: regionOverride }。

15.5.9 CalendarsOfLocale ( loc )

The implementation-defined abstract operation CalendarsOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Array. 以下算法引用 Unicode Technical Standard #35 Part 4 Dates, Calendar Preference Data 中规定的 Locale 数据。 It performs the following steps when called:

  1. 如果 loc.[[Calendar]] 不是 undefined,则
    1. 返回 CreateArrayFromListloc.[[Calendar]] »)。
  2. preferenceRegionPreference(loc.[[Locale]])。
  3. regionpreference.[[Region]]
  4. regionOverridepreference.[[RegionOverride]]
  5. 如果 regionOverride 不是 undefined,且 regionOverride 的日历偏好数据可用,则
    1. lookupRegionregionOverride
  6. 否则,
    1. lookupRegionregion
  7. list 为一个新的空 List
  8. availableCalendarsAvailableCalendars()。
  9. calendarsInUse 为在 lookupRegion 中日期和时间格式化常用的唯一日历类型List,按在 lookupRegion 中的使用偏好降序排序。如果没有 lookupRegion 的日历偏好数据,则该 List 为空。
  10. calendarsInUse 的每个元素 identifier,执行
    1. canonicalCanonicalizeUValue("ca", identifier)。
    2. 如果 identifiercanonicalavailableCalendars 包含 identifier,则
      1. identifier 追加到 list
  11. 如果 list 为空,则将 list 设置为 « "gregory" »。
  12. 返回 CreateArrayFromList(list)。

15.5.10 CollationsOfLocale ( loc )

The implementation-defined abstract operation CollationsOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Array. It performs the following steps when called:

  1. 如果 loc.[[Collation]] 不是 undefined,则
    1. 返回 CreateArrayFromListloc.[[Collation]] »)。
  2. languageGetLocaleLanguage(loc.[[Locale]])。
  3. 如果 language 不是 "und",则
    1. matchLookupMatchingLocaleByPrefix(%Intl.Collator%.[[AvailableLocales]], « loc.[[Locale]] »)。
    2. 如果 match 不是 undefined,则令 foundLocalematch.[[locale]];否则令 foundLocaleDefaultLocale()。
    3. foundLocaleData%Intl.Collator%.[[SortLocaleData]].[[<foundLocale>]]。
    4. listfoundLocaleData.[[co]] 的副本。
    5. 断言:list[0] 是 null
    6. list 中移除第一个元素。
  4. 否则,
    1. list 为 « "emoji", "eor" »。
  5. sortedlist 的副本,按字典序码元顺序排序。
  6. 返回 CreateArrayFromList(sorted)。

15.5.11 HourCyclesOfLocale ( loc )

The implementation-defined abstract operation HourCyclesOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Array. 以下算法引用 Unicode Technical Standard #35 Part 4 Dates, Time Data 中规定的 Locale 数据。 It performs the following steps when called:

  1. 如果 loc.[[HourCycle]] 不是 undefined,则
    1. 返回 CreateArrayFromListloc.[[HourCycle]] »)。
  2. preferenceRegionPreference(loc.[[Locale]])。
  3. regionpreference.[[Region]]
  4. regionOverridepreference.[[RegionOverride]]
  5. 如果 regionOverride 不是 undefined,且 regionOverride 的时间数据可用,则
    1. lookupRegionregionOverride
  6. 否则,
    1. lookupRegionregion
  7. list 为唯一小时周期标识符的 List,它们必须是小写 String 值,表示 12 小时格式("h11""h12")或 24 小时格式("h23""h24"),按在 lookupRegion 中日期和时间格式化常用的偏好降序排序。如果没有 lookupRegion 的时间数据,则该 List 为空。
  8. 如果 list 为空,则将 list 设置为 « "h23" »。
  9. 返回 CreateArrayFromList(list)。

15.5.12 NumberingSystemsOfLocale ( loc )

The implementation-defined abstract operation NumberingSystemsOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Array. It performs the following steps when called:

  1. 如果 loc.[[NumberingSystem]] 不是 undefined,则
    1. 返回 CreateArrayFromListloc.[[NumberingSystem]] »)。
  2. matchLookupMatchingLocaleByPrefix(%Intl.NumberFormat%.[[AvailableLocales]], « loc.[[Locale]] »)。
  3. 如果 match 不是 undefined,则
    1. foundLocalematch.[[locale]]
    2. foundLocaleData%Intl.NumberFormat%.[[LocaleData]].[[<foundLocale>]]。
    3. numberingSystemsfoundLocaleData.[[nu]]
    4. list 为 « numberingSystems[0] »。
  4. 否则,
    1. list 为 « "latn" »。
  5. 返回 CreateArrayFromList(list)。

15.5.13 TimeZonesOfLocale ( loc )

The implementation-defined abstract operation TimeZonesOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Array 或 undefined. It performs the following steps when called:

  1. regionGetLocaleRegion(loc.[[Locale]])。
  2. 如果 regionundefined,则返回 undefined
  3. list 为唯一规范时区标识符的 List,它们必须是表示 IANA Time Zone Database 规范 Zone 名称的 String 值,并且是在 region 中常用的时区。如果 region 中没有常用时区,则该 List 为空。该 List 按字典序码元顺序排序。
  4. 返回 CreateArrayFromList( list )。

15.5.14 TextDirectionOfLocale ( loc )

The implementation-defined abstract operation TextDirectionOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 String 或 undefined. 以下算法引用 Unicode Technical Standard #35 Part 1 Core, Script Metadata 中规定的 Locale 数据。 It performs the following steps when called:

  1. localeloc.[[Locale]]
  2. scriptGetLocaleScript(locale)。
  3. 如果 scriptundefined,则
    1. maximal 为将 Add Likely Subtags 算法应用于 locale 的结果。如果发出错误信号,则返回 undefined
    2. script 设置为 GetLocaleScript(maximal)。
    3. 如果 scriptundefined,则返回 undefined
  4. 如果 script 中一行内字符的默认一般排序方向是从右到左,则返回 "rtl"
  5. 如果 script 中一行内字符的默认一般排序方向是从左到右,则返回 "ltr"
  6. 返回 undefined
Note 1
当无法确定 script 中一行内字符的默认一般排序方向,或该方向既不是从右到左也不是从左到右时,将返回 undefined
Note 2
某种语言的文本可能有多个可能方向。用某种文字书写的某种语言的文本也可能有多个可能方向。因此,如果与一段文本相关的元数据中包含方向信息,则该方向信息应被视为主要事实来源。TextDirectionOfLocale 返回的信息只应在没有与文本关联的元数据可提供文本方向信息时用作回退机制。它只应在方向信息不存在但语言信息已知时使用。Web 开发者不应过度依赖此 API 来决定文本方向。

15.5.15 WeekdayToUValue ( fw )

The abstract operation WeekdayToUValue takes argument fw (一个 String) and returns 一个 String. 它将以数字表示星期几的字符串转换为 Unicode First Day Identifier,该标识符定义于 Unicode Technical Standard #35 Part 1 Core Section 3.6.1 Key and Type Definitions,并原样返回任何其他字符串。 It performs the following steps when called:

  1. Table 26 的每一行(表头行除外),按表格顺序,执行
    1. weekday 为当前行的 Weekday 值。
    2. string 为当前行的 String 值。
    3. 如果 fw 等于 weekday,则返回 string
  2. 返回 fw
Table 26: Weekday 字符串和值
Weekday String
"0" "sun" 7𝔽
"1" "mon" 1𝔽
"2" "tue" 2𝔽
"3" "wed" 3𝔽
"4" "thu" 4𝔽
"5" "fri" 5𝔽
"6" "sat" 6𝔽
"7" "sun" 7𝔽

15.5.16 WeekdayUValueToNumber ( fw )

The abstract operation WeekdayUValueToNumber takes argument fw (一个 String) and returns 一个整数 Number 或 undefined. 它将定义于 Unicode Technical Standard #35 Part 1 Core Section 3.6.1 Key and Type DefinitionsUnicode First Day Identifier 转换为数字 ISO 8601 calendar day of week,并对任何其他字符串返回 undefined。 It performs the following steps when called:

  1. Table 26 的每一行(表头行除外),按表格顺序,执行
    1. string 为当前行的 String 值。
    2. value 为当前行的 Value 值。
    3. 如果 fw 等于 string,则返回 value
  2. 返回 undefined

15.5.17 WeekInfoOfLocale ( loc )

The implementation-defined abstract operation WeekInfoOfLocale takes argument loc (一个 Intl.Locale) and returns 一个 Record. 以下算法引用 Unicode Technical Standard #35 Part 4 Dates, Week Elements 中规定的 Locale 数据。 It performs the following steps when called:

  1. localeloc.[[Locale]]
  2. weekInfo 为一个 Record,其字段由 Table 27 定义,值基于 locale
  3. firstDayStringloc.[[FirstDayOfWeek]]
  4. 如果 firstDayString 不是 undefined,则
    1. firstDayWeekdayUValueToNumber(firstDayString)。
    2. 如果 firstDay 不是 undefined,则将 weekInfo.[[FirstDay]] 设置为 firstDay
  5. 返回 weekInfo
Note
Record 的返回值由 locale 决定,并符合 Unicode Technical Standard #35 Part 4 Dates, Week DataFirst Day Overrides 中概述的规范。
Table 27: WeekInfo Record 字段
字段名称 含义
[[FirstDay]] 某个日历日的 ISO 8601 calendar day of week,即其在以 Monday 为 1𝔽 开始、以 Sunday 为 7𝔽 结束的周日历日序列中的从 1 开始的序数位置。 在日历用途上,星期中的哪一天被视为“第一天”。
[[Weekend]] 一个由一个或多个 ISO 8601 calendar day of week 整数 Number 值组成的 List,范围为 1𝔽(Monday)到 7𝔽(Sunday),按数值升序排列。 表示星期中的哪些天在日历用途上被视为“weekend”一部分的工作日值列表。注意,weekend 的天数可能因 locale 而异,也可能不连续。

16 NumberFormat 对象

16.1 Intl.NumberFormat 构造函数

Intl.NumberFormat 构造函数:

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

Intl 对象的所有服务构造函数属性共有的行为在 9.1 中规定。

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

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

  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]], locales, options, « coerce-options »)。
  4. options 设置为 optionsResolution.[[Options]]
  5. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  6. numberFormat.[[Locale]] 设置为 resolvedLocale.[[Locale]]
  7. numberFormat.[[LocaleData]] 设置为 resolvedLocale.[[LocaleData]]
  8. numberFormat.[[NumberingSystem]] 设置为 resolvedLocale.[[nu]]
  9. 执行 ? SetNumberFormatUnitOptions(numberFormat, options)。
  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(numberFormat, options, mnfdDefault, mxfdDefault, notation)。
  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 Note 1 的规范性可选构造函数模式,则
    1. thisthis 值。
    2. 返回 ? ChainNumberFormat(numberFormat, NewTarget, this)。
  27. 返回 numberFormat

16.1.1.1 ChainNumberFormat ( numberFormat, newTarget, this )

The abstract operation ChainNumberFormat takes arguments numberFormat (一个 Intl.NumberFormat), newTarget (一个 ECMAScript 语言值), and this (一个 ECMAScript 语言值) and returns 要么是包含一个 Object 的正常完成,要么是一个抛出完成. It performs the following steps when called:

  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 ( intlObj, options, mnfdDefault, mxfdDefault, notation )

The abstract operation SetNumberFormatDigitOptions takes arguments intlObj (一个 Object), options (一个 Object), mnfdDefault (一个整数), mxfdDefault (一个整数), and notation (一个 String) and returns 要么是包含 unused 的正常完成,要么是一个抛出完成. 它填充 intlObj 中影响 locale 无关数字舍入的内部槽(见 16.5.3)。 It performs the following steps when called:

  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(mxsd, intlObj.[[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(mnfdDefault, mxfd)。
      4. 否则如果 mxfdundefined,则将 mxfd 设置为 max(mxfdDefault, mnfd)。
      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 ( intlObj, options )

The abstract operation SetNumberFormatUnitOptions takes arguments intlObj (一个 Intl.NumberFormat) and options (一个 Object) and returns 要么是包含 unused 的正常完成,要么是一个抛出完成. 它将用户指定的与单位相关的选项解析到 intlObj 上。 It performs the following steps when called:

  1. style 为 ? GetOption(options, "style", string, « "decimal", "percent", "currency", "unit" », "decimal")。
  2. intlObj.[[Style]] 设置为 style
  3. currency 为 ? GetOption(options, "currency", string, empty, undefined)。
  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", string, empty, undefined)。
  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]] 设置为 currencyASCII-uppercase
    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 ] )

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

  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" } »。

Note 1
Unicode Technical Standard #35 Part 1 Core, Section 3.6.1 Key and Type Definitions 描述了三个与数字格式化相关的 locale 扩展键:用于货币的 "cu"、用于货币格式样式的 "cf",以及用于编号系统的 "nu"。不过,Intl.NumberFormat 要求货币格式的货币通过选项对象中的 currency 属性指定,而货币格式的货币格式样式通过选项对象中的 currencySign 属性指定。

[[LocaleData]] 内部槽的值在 9.1 中描述的约束范围内由实现定义,并满足以下额外约束:

  • [[LocaleData]] 的任何 locale 字段中 "nu" 字段的值所在的 List 不得包含值 "native""traditio""finance"
  • 对于所有 locale 值 locale[[LocaleData]].[[<locale>]] 必须具有一个 [[patterns]] 字段。该字段的值必须是一个 Record,该 Record 必须具有四种数字格式样式名称对应的字段:"decimal""percent""currency""unit"
  • 上述两个字段 "currency""unit" 必须是 Records,且至少具有一个字段 "fallback""currency" 可以具有与 6.3 中货币代码对应的键作为额外字段。 "currency" 的每个字段都必须是一个 Record,该 Record 的字段对应于可能的 currencyDisplay 值:"code""symbol""narrowSymbol""name"。 这些字段中的每一个都必须包含一个 Record,该 Record 的字段对应于可能的 currencySign 值:"standard""accounting""unit" 字段(属于 [[LocaleData]].[[<locale>]])除必需字段 "fallback" 外,还可以具有额外字段,其键对应于 6.6 中对应的核心测量单位标识符。 "unit" 的每个字段都必须是一个 Record,该 Record 的字段对应于可能的 unitDisplay 值:"narrow""short""long"
  • 目前为止为 patterns 树描述的所有叶字段("decimal""percent""currency" 的曾孙字段,以及 "unit" 的孙字段)都必须是具有键 "positivePattern""zeroPattern""negativePattern"Records
  • 前述字段(依赖符号的 pattern 字段)的值必须是字符串值,且必须包含子字符串 "{number}""positivePattern" 必须包含子字符串 "{plusSign}" 但不包含 "{minusSign}""negativePattern" 必须包含子字符串 "{minusSign}" 但不包含 "{plusSign}";并且 "zeroPattern" 不得包含 "{plusSign}""{minusSign}"。 此外,"percent" 字段内的值还必须包含子字符串 "{percentSign}""currency" 字段内的值还必须包含以下一个或多个子字符串:"{currencyCode}""{currencyPrefix}""{currencySuffix}""unit" 字段内的值还必须包含以下一个或多个子字符串:"{unitPrefix}""{unitSuffix}"。 当 pattern 字符串被解释为 UTF-16 编码码点序列时,如 ECMA-2626.1.4 中所述,不得包含 Unicode Standard 指定的 General Category "Number, decimal digit" 中的任何码点。
  • 对于所有 locale 值 locale[[LocaleData]].[[<locale>]] 还必须具有一个 [[notationSubPatterns]] 字段。该字段的值必须是一个 Record,该 Record 必须具有两个字段:[[scientific]][[compact]][[scientific]] 字段必须是一个包含子字符串 "{number}""{scientificSeparator}""{scientificExponent}" 的字符串值。[[compact]] 字段必须是一个具有两个字段的 Record"short""long"。这些字段中的每一个都必须是一个 Record,其整数键对应于实现为 compact notation 支持的所有离散数量级。这些字段中的每一个都必须是一个字符串值,该字符串值可以包含子字符串 "{number}"。从 "short" 派生的字符串必须包含子字符串 "{compactSymbol}",从 "long" 派生的字符串必须包含子字符串 "{compactName}"
Note 2
建议实现使用 Common Locale Data Repository 提供的 locale 数据(可在 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 ( )

该函数提供对对象初始化期间计算出的 locale 和选项的访问。

  1. nfthis 值。
  2. 如果实现支持 4.3 Note 1 的规范性可选构造函数模式,则
    1. nf 设置为 ? UnwrapNumberFormat(nf)。
  3. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  4. optionsOrdinaryObjectCreate(%Object.prototype%)。
  5. Table 28 的每一行(表头行除外),按表格顺序,执行
    1. propertyKey 为当前行的 Property 值。
    2. valuenf 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 如果 value 不是 undefined,则
      1. 如果当前行中存在 Conversion 值,则
        1. 断言:当前行的 Conversion 值是 number
        2. value 设置为 𝔽(value)。
      2. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  6. 返回 options
Table 28: 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 是一个访问器属性,其 set 访问器函数是 undefined。其 get 访问器函数执行以下步骤:

  1. nfthis 值。
  2. 如果实现支持 4.3 Note 1 的规范性可选构造函数模式,则
    1. nf 设置为 ? UnwrapNumberFormat(nf)。
  3. 执行 ? RequireInternalSlot(nf, [[InitializedNumberFormat]])。
  4. 如果 nf.[[BoundFormat]]undefined,则
    1. func 为一个新的内置函数对象,如 Number Format Functions(16.5.2)中所定义。
    2. func.[[NumberFormat]] 设置为 nf
    3. nf.[[BoundFormat]] 设置为 func
  5. 返回 nf.[[BoundFormat]]
Note
返回的函数绑定到 nf,因此它可以直接传递给 Array.prototype.map 或其他函数。 这被视为历史遗留产物,是一个新功能不再遵循的约定的一部分,但为保持与现有程序的兼容性而保留。

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

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

  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 )

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

  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 )

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

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

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

%Symbol.toStringTag% 属性的初始值是 String 值 "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]] 是一个 String 值,带有其本地化用于格式化的 locale 的语言标签
  • [[LocaleData]] 是一个 Record,表示实现可用于格式化的数据。它是 %Intl.NumberFormat%.[[LocaleData]] 中与 [[Locale]] 的值或其前缀关联的一个条目的值。
  • [[NumberingSystem]] 是一个 String 值,表示用于格式化的 Unicode Number System Identifier
  • [[Style]] 是 String 值 "decimal""currency""percent""unit" 之一,用于标识正在测量的数量类型。
  • [[Currency]] 是一个 String 值,带有货币代码,用于标识在使用 "currency" 单位类型进行格式化时要使用的货币。它仅在 [[Style]] 的值为 "currency" 时使用。
  • [[CurrencyDisplay]] 是 String 值 "code""symbol""narrowSymbol""name" 之一,指定在使用 "currency" 样式进行格式化时,是将货币显示为 ISO 4217 字母货币代码、本地化货币符号,还是本地化货币名称。它仅在 [[Style]] 的值为 "currency" 时使用。
  • [[CurrencySign]] 是 String 值 "standard""accounting" 之一,指定是否以会计格式渲染负数,通常用括号表示。它仅在 [[Style]] 的值为 "currency"[[SignDisplay]] 不是 "never" 时使用。
  • [[Unit]] 是一个 core unit identifier。它仅在 [[Style]] 的值为 "unit" 时使用。
  • [[UnitDisplay]] 是 String 值 "short""narrow""long" 之一,指定在使用 "unit" 样式进行格式化时,是将单位显示为符号、窄符号,还是本地化长名称。它仅在 [[Style]] 的值为 "unit" 时使用。
  • [[MinimumIntegerDigits]] 是一个非负整数,指示要使用的最小整数位数。必要时,数字会用前导零填充。
  • [[MinimumFractionDigits]][[MaximumFractionDigits]] 是非负整数,指示要使用的最小和最大小数位数。必要时,数字会被舍入或用尾随零填充。这些属性仅在 [[RoundingType]]fraction-digitsmore-precisionless-precision 时使用。
  • [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 是正整数,指示要显示的最小和最大有效数字位数。如果存在,格式化器会使用显示指定有效数字数量所需的任意小数位数。这些属性仅在 [[RoundingType]]significant-digitsmore-precisionless-precision 时使用。
  • [[UseGrouping]] 是一个 Boolean 或 String 值,指示应在什么条件下使用分组分隔符。分组分隔符的位置,以及是否为格式化后的数字显示分组分隔符,由实现定义。值 "always" 提示实现尽可能显示分组分隔符;"min2" 表示当某个分组中至少有 2 位数字时;"auto" 表示当 locale 偏好为格式化后的数字使用分组分隔符时。值 false 禁用分组分隔符。
  • [[RoundingType]] 是值 fraction-digitssignificant-digitsmore-precisionless-precision 之一,指示要使用的舍入策略。如果为 fraction-digits,则格式化后的数字会根据 [[MinimumFractionDigits]][[MaximumFractionDigits]] 舍入,如上所述。如果为 significant-digits,则格式化后的数字会根据 [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 舍入,如上所述。如果为 more-precisionless-precision,则使用全部四个设置,并使用特定规则来消解何时使用一组设置而非另一组设置。[[RoundingType]] 派生自 "roundingPriority" 选项。
  • [[ComputedRoundingPriority]] 是 String 值 "auto""morePrecision""lessPrecision" 之一。它仅在 16.3.2 中用于将 [[RoundingType]] 转换回有效的 "roundingPriority" 选项。
  • [[Notation]] 是 String 值 "standard""scientific""engineering""compact" 之一,指定格式化后的数字应不缩放显示,缩放到科学记数法中十的幂的个位,缩放到科学记数法中十的幂的最近千位,还是缩放到最近的 ILD compact decimal notation 的十的幂并带有对应的 compact decimal notation 词缀。
  • [[CompactDisplay]]"short""long"undefined 之一,指定是否以短形式("5K")或长形式("5 thousand")显示 compact notation 词缀。当且仅当 [[Notation]] 的值不是 "compact" 时,它为 undefined
  • [[SignDisplay]] 是 String 值 "auto""always""never""exceptZero""negative" 之一,指定何时包含符号(非 "auto" 选项分别对应于总是包含、从不包含、仅对非零数字包含,或仅对非零负数包含)。 在科学记数法中,此槽影响尾数的符号显示,但不影响指数。
  • [[RoundingIncrement]] 是一个整数,它能将 10、100、1000 或 10000 均匀分为十分之一、五分之一、四分之一或二分之一。它指示应相对于计算出的舍入量级以何种增量进行舍入。例如,如果 [[MaximumFractionDigits]] 为 2 且 [[RoundingIncrement]] 为 5,则格式化后的数字舍入到最接近的 0.05(“nickel rounding”)。
  • [[RoundingMode]] 是一个 舍入模式,为 Table 29 的 Identifier 列中的 String 值之一。
  • [[TrailingZeroDisplay]] 是 String 值 "auto""stripIfInteger" 之一,指示如果格式化后的数字是整数(即没有非零小数位),是否去除尾随零。
Table 29: 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]
Note
这些示例用于说明每个选项的独特行为。⬆️ 表示“解析朝向正无穷大”;⬇️ 表示“解析朝向负无穷大”。

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

16.5 NumberFormat 对象的抽象操作

16.5.1 CurrencyDigits ( currency )

The implementation-defined abstract operation CurrencyDigits takes argument currency (一个 String) and returns 一个非负整数. It performs the following steps when called:

  1. 断言:IsWellFormedCurrencyCode(currency) 是 true
  2. 返回一个非负整数,指示在格式化与 currency 对应的货币数量时使用的小数位数。如果没有关于要使用的位数的可用信息,则返回 2。

16.5.2 Number Format Functions

Number format function 是一个具有 [[NumberFormat]] 内部槽的匿名内置函数。

当 Number format function func 以可选实参 value 调用时,执行以下步骤:

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

Number format function 的 "length" 属性是 1𝔽

16.5.3 FormatNumericToString ( intlObj, x )

The abstract operation FormatNumericToString takes arguments intlObj (一个 Object) and x (一个数学值或 negative-zero) and returns 一个带有字段 [[RoundedNumber]](一个数学值或 negative-zero)和 [[FormattedString]](一个 String)的 Record. 它根据 intlObj 的内部槽将 x 舍入为 Intl 数学值[[RoundedNumber]] 字段包含舍入后的结果值,[[FormattedString]] 字段包含根据 intlObj 的内部槽格式化后的该结果的 String 值表示。 It performs the following steps when called:

  1. 断言:intlObj 具有 [[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(intlObj.[[RoundingMode]], sign)。
  5. 如果 intlObj.[[RoundingType]]significant-digits,则
    1. resultToRawPrecision(x, intlObj.[[MinimumSignificantDigits]], intlObj.[[MaximumSignificantDigits]], unsignedRoundingMode)。
  6. 否则如果 intlObj.[[RoundingType]]fraction-digits,则
    1. resultToRawFixed(x, intlObj.[[MinimumFractionDigits]], intlObj.[[MaximumFractionDigits]], intlObj.[[RoundingIncrement]], unsignedRoundingMode)。
  7. 否则,
    1. significantResultToRawPrecision(x, intlObj.[[MinimumSignificantDigits]], intlObj.[[MaximumSignificantDigits]], unsignedRoundingMode)。
    2. fractionResultToRawFixed(x, intlObj.[[MinimumFractionDigits]], intlObj.[[MaximumFractionDigits]], intlObj.[[RoundingIncrement]], unsignedRoundingMode)。
    3. 如果 fractionResult.[[RoundingMagnitude]] < significantResult.[[RoundingMagnitude]],则令 fixedIsMorePrecisetrue;否则令 fixedIsMorePrecisefalse
    4. 如果 intlObj.[[RoundingType]]more-precisionfixedIsMorePrecisetrue,则
      1. resultfractionResult
    5. 否则如果 intlObj.[[RoundingType]]less-precisionfixedIsMorePrecisefalse,则
      1. resultfractionResult
    6. 否则,
      1. resultsignificantResult
  8. x 设置为 result.[[RoundedNumber]]
  9. stringresult.[[FormattedString]]
  10. 如果 intlObj.[[TrailingZeroDisplay]]"stripIfInteger"x modulo 1 = 0,则
    1. iStringIndexOf(string, ".", 0)。
    2. 如果 i 不是 not-found,则将 string 设置为 string 从 0 到 i 的子字符串。
  11. intresult.[[IntegerDigitsCount]]
  12. minIntDigitsintlObj.[[MinimumIntegerDigits]]
  13. 如果 int < minIntDigits,则
    1. forwardZeros 为由 minIntDigits - int 次出现的码元 0x0030 (DIGIT ZERO) 组成的 String。
    2. string 设置为 forwardZerosstring 的字符串拼接。
  14. 如果 signnegative,则
    1. 如果 x 是 0,则将 x 设置为 negative-zero。否则,将 x 设置为 -x
  15. 返回 Record { [[RoundedNumber]]: x, [[FormattedString]]: string }。

16.5.4 PartitionNumberPattern ( numberFormat, x )

The abstract operation PartitionNumberPattern takes arguments numberFormat (一个初始化为 NumberFormat 的对象) and x (一个 Intl 数学值) and returns 一个带有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList. 它根据 numberFormat 的有效 locale 和格式化选项,创建表示 x 数学值的 parts。 It performs the following steps when called:

  1. exponent 为 0。
  2. 如果 xnot-a-number,则
    1. formattedString 为一个表示 NaN 值的 ILD String 值。
  3. 否则如果 xpositive-infinity,则
    1. formattedString 为一个表示正无穷大的 ILD String 值。
  4. 否则如果 xnegative-infinity,则
    1. formattedString 为一个表示负无穷大的 ILD String 值。
  5. 否则,
    1. 如果 x 不是 negative-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. formattedStringformatNumberResult.[[FormattedString]]
    4. x 设置为 formatNumberResult.[[RoundedNumber]]
  6. patternGetNumberFormatPattern(numberFormat, x)。
  7. result 为一个新的空 List
  8. patternPartsPartitionPattern(pattern)。
  9. patternParts 的每个 Record { [[Type]], [[Value]] } patternPart,执行
    1. partTypepatternPart.[[Type]]
    2. 如果 partType"literal",则
      1. Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } 追加到 result
    3. 否则如果 partType"number",则
      1. notationSubPartsPartitionNotationSubPattern(numberFormat, x, formattedString, exponent)。
      2. result 设置为 resultnotationSubParts 的列表拼接。
    4. 否则如果 partType"plusSign",则
      1. plusSignSymbol 为表示加号的 ILND String。
      2. Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } 追加到 result
    5. 否则如果 partType"minusSign",则
      1. minusSignSymbol 为表示减号的 ILND String。
      2. Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } 追加到 result
    6. 否则如果 partType"percentSign"numberFormat.[[Style]]"percent",则
      1. percentSignSymbol 为表示百分号的 ILND String。
      2. Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } 追加到 result
    7. 否则如果 partType"unitPrefix"numberFormat.[[Style]]"unit",则
      1. unitnumberFormat.[[Unit]]
      2. unitDisplaynumberFormat.[[UnitDisplay]]
      3. unitString 为一个 ILD String 值,表示以 unitDisplay 形式位于 x 之前的 unit,它在具有不同复数形式的语言中可能取决于 x
      4. Record { [[Type]]: "unit", [[Value]]: unitString } 追加到 result
    8. 否则如果 partType"unitSuffix"numberFormat.[[Style]]"unit",则
      1. unitnumberFormat.[[Unit]]
      2. unitDisplaynumberFormat.[[UnitDisplay]]
      3. unitString 为一个 ILD String 值,表示以 unitDisplay 形式位于 x 之后的 unit,它在具有不同复数形式的语言中可能取决于 x
      4. Record { [[Type]]: "unit", [[Value]]: unitString } 追加到 result
    9. 否则如果 partType"currencyCode"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. Record { [[Type]]: "currency", [[Value]]: currency } 追加到 result
    10. 否则如果 partType"currencyPrefix"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. currencyDisplaynumberFormat.[[CurrencyDisplay]]
      3. currencyString 为一个 ILD String 值,表示以 currencyDisplay 形式位于 x 之前的 currency,它在具有不同复数形式的语言中可能取决于 x
      4. Record { [[Type]]: "currency", [[Value]]: currencyString } 追加到 result
    11. 否则如果 partType"currencySuffix"numberFormat.[[Style]]"currency",则
      1. currencynumberFormat.[[Currency]]
      2. currencyDisplaynumberFormat.[[CurrencyDisplay]]
      3. currencyString 为一个 ILD String 值,表示以 currencyDisplay 形式位于 x 之后的 currency,它在具有不同复数形式的语言中可能取决于 x。如果实现没有这种 currency 表示,则使用 currency 本身。
      4. Record { [[Type]]: "currency", [[Value]]: currencyString } 追加到 result
    12. 否则,
      1. unknown 为一个基于 xpartTypeILND String。
      2. Record { [[Type]]: "unknown", [[Value]]: unknown } 追加到 result
  10. 返回 result

16.5.5 PartitionNotationSubPattern ( numberFormat, x, formattedString, exponent )

The abstract operation PartitionNotationSubPattern takes arguments numberFormat (一个 Intl.NumberFormat), x (一个 Intl 数学值), formattedString (一个 String), and exponent (一个整数) and returns 一个带有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList. x 是应用舍入后的 Intl 数学值formattedString 是一个中间格式化字符串。 它根据 numberFormat 的有效 locale 和格式化选项,为数字和 notation 创建对应的 parts。 It performs the following steps when called:

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

16.5.6 FormatNumeric ( numberFormat, x )

The abstract operation FormatNumeric takes arguments numberFormat (一个 Intl.NumberFormat) and x (一个 Intl 数学值) and returns 一个 String. It performs the following steps when called:

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

16.5.7 FormatNumericToParts ( numberFormat, x )

The abstract operation FormatNumericToParts takes arguments numberFormat (一个 Intl.NumberFormat) and x (一个 Intl 数学值) and returns 一个 Array. It performs the following steps when called:

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

16.5.8 ToRawPrecision ( x, minPrecision, maxPrecision, unsignedRoundingMode )

The abstract operation ToRawPrecision takes arguments x (一个非负数学值), minPrecision (闭区间 1 到 21 内的一个整数), maxPrecision (闭区间 1 到 21 内的一个整数), and unsignedRoundingMode (来自 Table 31 的 Unsigned Rounding Mode 列的规范类型,或 undefined) and returns 一个带有字段 [[FormattedString]](一个 String)、[[RoundedNumber]](一个数学值)、[[IntegerDigitsCount]](一个整数)和 [[RoundingMagnitude]](一个整数)的 Record.

它涉及求解以下方程,该方程在给定整数输入时返回一个有效数学值:

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

It performs the following steps when called:

  1. pmaxPrecision
  2. 如果 x = 0,则
    1. m 为由 p 次出现的码元 0x0030 (DIGIT ZERO) 组成的 String。
    2. e 为 0。
    3. xFinal 为 0。
  3. 否则,
    1. n1e1 均为整数,r1 为数学值,满足 r1 = ToRawPrecisionFn(n1, e1, p),并且 r1x,且 r1 最大化。
    2. n2e2 均为整数,r2 为数学值,满足 r2 = ToRawPrecisionFn(n2, e2, p),并且 r2x,且 r2 最小化。
    3. xFinalApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode)。
    4. 如果 xFinalr1,则
      1. nn1
      2. ee1
    5. 否则,
      1. nn2
      2. ee2
    6. m 为由 n 的十进制表示中的数字组成的 String(按顺序,无前导零)。
  4. 如果 e ≥ (p - 1),则
    1. m 设置为 me - p + 1 次出现的码元 0x0030 (DIGIT ZERO) 的字符串拼接。
    2. inte + 1。
  5. 否则如果 e ≥ 0,则
    1. m 设置为 m 的前 e + 1 个码元、码元 0x002E (FULL STOP),以及 m 的剩余 p - (e + 1) 个码元的字符串拼接。
    2. inte + 1。
  6. 否则,
    1. 断言:e < 0。
    2. m 设置为 "0."、-(e + 1) 次出现的码元 0x0030 (DIGIT ZERO),以及 m 的字符串拼接。
    3. int 为 1。
  7. 如果 m 包含码元 0x002E (FULL STOP) 且 maxPrecision > minPrecision,则
    1. cutmaxPrecision - minPrecision
    2. 重复,当 cut > 0 且 m 的最后一个码元是 0x0030 (DIGIT ZERO) 时,
      1. m 中移除最后一个码元。
      2. cut 设置为 cut - 1。
    3. 如果 m 的最后一个码元是 0x002E (FULL STOP),则
      1. m 中移除最后一个码元。
  8. 返回 Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: ep+1 }。

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

The abstract operation ToRawFixed takes arguments x (一个非负数学值), minFraction (闭区间 0 到 100 内的一个整数), maxFraction (闭区间 0 到 100 内的一个整数), roundingIncrement (一个整数), and unsignedRoundingMode (来自 Table 31 的 Unsigned Rounding Mode 列的规范类型,或 undefined) and returns 一个带有字段 [[FormattedString]](一个 String)、[[RoundedNumber]](一个数学值)、[[IntegerDigitsCount]](一个整数)和 [[RoundingMagnitude]](一个整数)的 Record.

它涉及求解以下方程,该方程在给定整数输入时返回一个有效数学值:

ToRawFixedFn(n, f) = n × 10f

It performs the following steps when called:

  1. fmaxFraction
  2. n1 为整数,r1 为数学值,满足 r1 = ToRawFixedFn(n1, f),且 n1 modulo roundingIncrement = 0r1x,并且 r1 最大化。
  3. n2 为整数,r2 为数学值,满足 r2 = ToRawFixedFn(n2, f),且 n2 modulo roundingIncrement = 0r2x,并且 r2 最小化。
  4. xFinalApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode)。
  5. 如果 xFinalr1,则令 nn1。否则,令 nn2
  6. 如果 n = 0,则令 m"0"。否则,令 m 为由 n 的十进制表示中的数字组成的 String(按顺序,无前导零)。
  7. 如果 f ≠ 0,则
    1. km 的长度。
    2. 如果 kf,则
      1. z 为由 f + 1 - k 次出现的码元 0x0030 (DIGIT ZERO) 组成的 String 值。
      2. m 设置为 zm 的字符串拼接。
      3. k 设置为 f + 1。
    3. am 的前 k - f 个码元,并令 bm 的剩余 f 个码元。
    4. m 设置为 a"."b 的字符串拼接。
    5. inta 的长度。
  8. 否则,
    1. intm 的长度。
  9. cutmaxFraction - minFraction
  10. 重复,当 cut > 0 且 m 的最后一个码元是 0x0030 (DIGIT ZERO) 时,
    1. m 中移除最后一个码元。
    2. cut 设置为 cut - 1。
  11. 如果 m 的最后一个码元是 0x002E (FULL STOP),则
    1. m 中移除最后一个码元。
  12. 返回 Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: –f }。

16.5.10 UnwrapNumberFormat ( nf )

The abstract operation UnwrapNumberFormat takes argument nf (一个 ECMAScript 语言值) and returns 要么是包含一个 ECMAScript 语言值的正常完成,要么是一个抛出完成. 它返回其输入对象的 NumberFormat 实例,该实例要么是值本身,要么是按照 4.3 Note 1 的规范性可选构造函数模式由 %Intl.NumberFormat% 与之关联的值。 It performs the following steps when called:

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

16.5.11 GetNumberFormatPattern ( numberFormat, x )

The abstract operation GetNumberFormatPattern takes arguments numberFormat (一个 Intl.NumberFormat) and x (一个 Intl 数学值) and returns 一个 String. 它考虑数字格式对象中已解析的与单位相关的选项,以及正在格式化的最终缩放并舍入后的数字(一个 Intl 数学值),并返回一个 pattern,即如 16.2.3 中所述的 String 值。 It performs the following steps when called:

  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 )

The abstract operation GetNotationSubPattern takes arguments numberFormat (一个 Intl.NumberFormat) and exponent (一个整数) and returns 一个 String. 它考虑已解析的 notation 和 exponent,并返回 notation 子 pattern 的 String 值,如 16.2.3 中所述。 It performs the following steps when called:

  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 )

The abstract operation ComputeExponent takes arguments numberFormat (一个 Intl.NumberFormat) and x (一个数学值) and returns 一个整数. 它根据数字格式化设置计算用于缩放 x 的指数(十的幂)。 它处理诸如 999 舍入到 1000、需要不同指数的情况。 It performs the following steps when called:

  1. 如果 x = 0,则
    1. 返回 0。
  2. 如果 x < 0,则
    1. x = -x
  3. magnitudefloor(log10(x))。
  4. exponentComputeExponentForMagnitude(numberFormat, magnitude)。
  5. x 设为 x × 10-exponent
  6. formatNumberResultFormatNumericToString(numberFormat, x)。
  7. 如果 formatNumberResult.[[RoundedNumber]] = 0,则
    1. 返回 exponent
  8. newMagnitudefloor(log10(formatNumberResult.[[RoundedNumber]]))。
  9. 如果 newMagnitudemagnitude - exponent,则
    1. 返回 exponent
  10. 返回 ComputeExponentForMagnitude(numberFormat, magnitude + 1)。

16.5.14 ComputeExponentForMagnitude ( numberFormat, magnitude )

The abstract operation ComputeExponentForMagnitude takes arguments numberFormat (一个 Intl.NumberFormat) and magnitude (一个整数) and returns 一个整数. 它根据 locale 和期望的 notation(scientific、engineering 或 compact),计算用于缩放给定数量级(最高有效数字的十的幂)数字的指数。 It performs the following steps when called:

  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 整数,用于按当前 locale 的 compact notation 缩放给定数量级的数字。
    3. 返回 exponent

16.5.15 运行时语义:StringIntlMV

The syntax-directed operation 运行时语义:StringIntlMV takes no arguments.

Note

StringNumericLiteral 到 Number 值的转换整体上类似于 NumericLiteralNumericValue 的确定(见 12.9.3),但某些细节不同。

It is defined piecewise over the following productions:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. 返回 0。
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. 返回 StrNumericLiteral 的 StringIntlMV。
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. 返回 NonDecimalIntegerLiteral 的 MV。
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. aStrUnsignedDecimalLiteral 的 StringIntlMV。
  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 )

The abstract operation ToIntlMathematicalValue takes argument value (一个 ECMAScript 语言值) and returns 要么是包含一个 Intl 数学值的正常完成,要么是一个抛出完成. 它返回转换为 Intl 数学值后的 value,该值是一个数学值,并包含 positive-infinitynegative-infinitynot-a-numbernegative-zero。 此抽象操作类似于 7.1.3,但可以返回数学值而不是 Number 或 BigInt,从而可以表示精确的十进制值。 It performs the following steps when called:

  1. primValue 为 ? ToPrimitive(value, number)。
  2. 如果 primValue 是 BigInt,则返回 (primValue)。
  3. 如果 primValue 是 String,则
    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. intlMVliteral 的 StringIntlMV。
  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 )

The abstract operation GetUnsignedRoundingMode takes arguments roundingMode (一个舍入模式) and sign (negativepositive) and returns 来自 Table 31 的 Unsigned Rounding Mode 列的规范类型. 它返回应应用于数字绝对值的 rounding mode,以产生与将 roundingMode 应用于该数字的带符号值(如果 signnegative 则为负,否则为正)相同的结果。 It performs the following steps when called:

  1. 返回 Table 31 的 Unsigned Rounding Mode 列中的规范类型,所在行的 Identifier 列值为 roundingMode,且 Sign 列值为 sign
Table 31: 从 rounding mode 到 unsigned rounding mode 的转换
标识符 符号 Unsigned Rounding Mode
"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 )

The abstract operation ApplyUnsignedRoundingMode takes arguments x (一个数学值), r1 (一个数学值), r2 (一个数学值), and unsignedRoundingMode (来自 Table 31 的 Unsigned Rounding Mode 列的规范类型,或 undefined) and returns 一个数学值. 它考虑由下方 r1 和上方 r2 夹住的 x,并根据 unsignedRoundingMode 返回 r1r2。 It performs the following steps when called:

  1. 如果 xr1,则返回 r1
  2. 断言:r1 < x < r2
  3. 断言:unsignedRoundingMode 不是 undefined
  4. 如果 unsignedRoundingModezero,则返回 r1
  5. 如果 unsignedRoundingModeinfinity,则返回 r2
  6. d1xr1
  7. d2r2x
  8. 如果 d1 < d2,则返回 r1
  9. 如果 d2 < d1,则返回 r2
  10. 断言:d1d2
  11. 如果 unsignedRoundingModehalf-zero,则返回 r1
  12. 如果 unsignedRoundingModehalf-infinity,则返回 r2
  13. 断言:unsignedRoundingModehalf-even
  14. cardinality(r1 / (r2r1)) modulo 2
  15. 如果 cardinality 是 0,则返回 r1
  16. 返回 r2

16.5.19 PartitionNumberRangePattern ( numberFormat, x, y )

The abstract operation PartitionNumberRangePattern takes arguments numberFormat (一个 Intl.NumberFormat), x (一个 Intl 数学值), and y (一个 Intl 数学值) and returns 要么是包含一个带有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Source]](一个 String)的 RecordsList 的正常完成,要么是一个抛出完成. 它根据 xynumberFormat 的格式化选项,为本地化数字范围创建 parts。 It performs the following steps when called:

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

16.5.20 FormatApproximately ( numberFormat, result )

The abstract operation FormatApproximately takes arguments numberFormat (一个 Intl.NumberFormat) and result (一个带有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList) and returns 一个带有字段 [[Type]](一个 String)和 [[Value]](一个 String)的 RecordsList. 它修改 result,该值必须是 PartitionNumberPattern 中所述的 Record 值的 List,方式是为约等号添加一个新的 Record,该约等号可能取决于 numberFormat。 It performs the following steps when called:

  1. approximatelySign 为用于表示数字是近似值的 ILND String 值。
  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 )

The implementation-defined abstract operation CollapseNumberRange takes arguments numberFormat (一个 Intl.NumberFormat) and result (一个带有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Source]](一个 String)的 RecordsList) and returns 一个带有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Source]](一个 String)的 RecordsList. 它根据 numberFormat 的有效 locale 和格式化选项,通过移除冗余信息、解决内部不一致、在必要时替换字符,以及在必要时插入间距来修改 result(它必须是 PartitionNumberRangePattern 中构造出的 RecordsList)。随后返回得到的 List。该算法是 ILND 的,但不得引入歧义,使得当使用实参 List « start1, end1 » 调用 Intl.NumberFormat.prototype.formatRange ( start, end ) 的结果等于使用实参 List « start2, end2 » 调用的结果,而如果使用始终原样返回 result 的 CollapseNumberRange 平凡实现时,同样这些实参 Lists 的结果本不会相等。

例如,实现可以移除 range separator 之后表示货币符号的 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 )

The abstract operation FormatNumericRange takes arguments numberFormat (一个 Intl.NumberFormat), x (一个 Intl 数学值), and y (一个 Intl 数学值) and returns 要么是包含一个 String 的正常完成,要么是一个抛出完成. It performs the following steps when called:

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

16.5.23 FormatNumericRangeToParts ( numberFormat, x, y )

The abstract operation FormatNumericRangeToParts takes arguments numberFormat (一个 Intl.NumberFormat), x (一个 Intl 数学值), and y (一个 Intl 数学值) and returns 要么是包含一个 Array 的正常完成,要么是一个抛出完成. It performs the following steps when called:

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

17 PluralRules 对象

17.1 Intl.PluralRules 构造函数

Intl.PluralRules 构造函数:

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

Intl 对象的所有服务构造函数属性共有的行为在 9.1 中规定。

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

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

  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. options 设置为 optionsResolution.[[Options]]
  5. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  6. pluralRules.[[Locale]] 设置为 resolvedLocale.[[Locale]]
  7. type 为 ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal")。
  8. pluralRules.[[Type]] 设置为 type
  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. 如果 notation"compact",则
    1. pluralRules.[[CompactDisplay]] 设置为 compactDisplay
  13. 执行 ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3, notation)。
  14. 返回 pluralRules

17.2 Intl.PluralRules 构造函数的属性

Intl.PluralRules 构造函数:

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 ] )

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

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

17.2.3 内部槽

[[AvailableLocales]] 内部槽的值在 9.1 中描述的约束范围内由实现定义。

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

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

Note 1
Unicode Technical Standard #35 Part 1 Core, Section 3.6.1 Key and Type Definitions 未描述任何与复数化过程相关的 locale 扩展键。

[[LocaleData]] 内部槽的值在 9.1 中描述的约束范围内由实现定义。

Note 2
建议实现使用 Common Locale Data Repository 提供的 locale 数据(可在 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 ( )

该函数提供对对象初始化期间计算出的 locale 和选项的访问。

  1. prthis 值。
  2. 执行 ? RequireInternalSlot(pr, [[InitializedPluralRules]])。
  3. optionsOrdinaryObjectCreate(%Object.prototype%)。
  4. pluralCategories 为一个 Strings 的 List,包含选定 locale pr.[[Locale]]PluralRuleSelect 的所有可能结果,并按以下顺序排序:"zero""one""two""few""many""other"
  5. Table 32 的每一行(表头行除外),按表格顺序,执行
    1. propertyKey 为当前行的 Property 值。
    2. 如果 propertyKey"pluralCategories",则
      1. valueCreateArrayFromList(pluralCategories)。
    3. 否则,
      1. valuepr 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    4. 如果 value 不是 undefined,则
      1. 如果当前行中存在 Conversion 值,则
        1. 断言:当前行的 Conversion 值是 number
        2. value 设置为 𝔽(value)。
      2. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  6. 返回 options
Table 32: 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 )

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

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

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

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

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

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

%Symbol.toStringTag% 属性的初始值是 String 值 "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]] 是一个 String 值,带有复数规则使用其本地化的 locale 的语言标签
  • [[Type]] 是 String 值 "cardinal""ordinal" 之一,用于标识所使用的复数规则。
  • [[Notation]] 是 String 值 "standard""scientific""engineering""compact" 之一,用于标识所使用的 notation。
  • [[CompactDisplay]]"short""long"undefined 之一,指定是否以短形式("5K")或长形式("5 thousand")显示 compact notation 词缀,因为这在某些情况下会影响复数形式选择。当且仅当 [[Notation]] 的值不是 "compact" 时,它为 undefined
  • [[MinimumIntegerDigits]] 是一个非负整数,指示要使用的最小整数位数。
  • [[MinimumFractionDigits]][[MaximumFractionDigits]] 是非负整数,指示要使用的最小和最大小数位数。必要时,数字会被舍入或用尾随零填充。
  • [[MinimumSignificantDigits]][[MaximumSignificantDigits]] 是正整数,指示要使用的最小和最大小数位数。这些属性要么都不存在,要么都存在;如果存在,它们会覆盖最小和最大整数及小数位数。
  • [[RoundingType]] 是值 fraction-digitssignificant-digitsmore-precisionless-precision 之一,指示要使用的舍入策略,如 16.4 中所讨论。
  • [[ComputedRoundingPriority]] 是 String 值 "auto""morePrecision""lessPrecision" 之一。它仅在 17.3.2 中用于将 [[RoundingType]] 转换回有效的 "roundingPriority" 选项。
  • [[RoundingIncrement]] 是一个整数,它能将 10、100、1000 或 10000 均匀分为十分之一、五分之一、四分之一或二分之一。它指示应相对于计算出的舍入量级以何种增量进行舍入。例如,如果 [[MaximumFractionDigits]] 为 2 且 [[RoundingIncrement]] 为 5,则格式化后的数字舍入到最接近的 0.05(“nickel rounding”)。
  • [[RoundingMode]] 标识要使用的舍入模式
  • [[TrailingZeroDisplay]] 是 String 值 "auto""stripIfInteger" 之一,指示如果格式化后的数字是整数(即没有非零小数位),是否去除尾随零。

17.5 PluralRules 对象的抽象操作

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

The implementation-defined abstract operation PluralRuleSelect takes arguments locale (一个语言标签), type ("cardinal""ordinal"), notation (一个 String), compactDisplay ("short""long"), and decimalString (一个十进制 String) and returns "zero""one""two""few""many""other". 返回的 String 根据对应 localetypenotationcompactDisplay 表征 decimalString 的复数类别。

17.5.2 ResolvePlural ( pluralRules, n )

The abstract operation ResolvePlural takes arguments pluralRules (一个 Intl.PluralRules) and n (一个 Intl 数学值) and returns 一个带有字段 [[PluralCategory]]"zero""one""two""few""many""other")和 [[FormattedString]](一个 String)的 Record. 返回的 Record 包含两个字符串值字段,根据有效 locale 和 pluralRules 的内部槽描述 n[[PluralCategory]] 表征其复数类别,而 [[FormattedString]] 包含其格式化表示。 It performs the following steps when called:

  1. 如果 nnot-a-number,则
    1. formattedString 为一个表示 NaN 值的 ILD String 值。
    2. 返回 Record { [[PluralCategory]]: "other", [[FormattedString]]: formattedString }。
  2. 如果 npositive-infinity,则
    1. formattedString 为一个表示正无穷大的 ILD String 值。
    2. 返回 Record { [[PluralCategory]]: "other", [[FormattedString]]: formattedString }。
  3. 如果 nnegative-infinity,则
    1. formattedString 为一个表示负无穷大的 ILD String 值。
    2. 返回 Record { [[PluralCategory]]: "other", [[FormattedString]]: formattedString }。
  4. resFormatNumericToString(pluralRules, n)。
  5. formattedStringres.[[FormattedString]]
  6. localepluralRules.[[Locale]]
  7. typepluralRules.[[Type]]
  8. notationpluralRules.[[Notation]]
  9. compactDisplaypluralRules.[[CompactDisplay]]
  10. pluralCategoryPluralRuleSelect(locale, type, notation, compactDisplay, formattedString)。
  11. 返回 Record { [[PluralCategory]]: pluralCategory, [[FormattedString]]: formattedString }。

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

The implementation-defined abstract operation PluralRuleSelectRange takes arguments locale (一个语言标签), type ("cardinal""ordinal"), notation (一个 String), compactDisplay ("short""long"), xp ("zero""one""two""few""many""other"), and yp ("zero""one""two""few""many""other") and returns "zero""one""two""few""many""other". 它执行一个依赖于实现的算法,将分别表征范围起点和终点的复数类别 String 值 xpyp,映射到表示整个范围的复数形式的已解析 String 值,该范围由对应 localetypenotationcompactDisplay 表示;或者映射到 String 值 "other"

17.5.4 ResolvePluralRange ( pluralRules, x, y )

The abstract operation ResolvePluralRange takes arguments pluralRules (一个 Intl.PluralRules), x (一个 Intl 数学值), and y (一个 Intl 数学值) and returns 要么是包含 "zero""one""two""few""many""other" 之一的正常完成,要么是一个抛出完成. 返回的 String 值根据有效 locale 和 pluralRules 的内部槽,表示从 x 开始到 y 结束的范围的复数形式。 It performs the following steps when called:

  1. 如果 xnot-a-numberynot-a-number,则抛出一个 RangeError 异常。
  2. xResultResolvePlural(pluralRules, x)。
  3. yResultResolvePlural(pluralRules, y)。
  4. 如果 xResult.[[FormattedString]]yResult.[[FormattedString]],则
    1. 返回 xResult.[[PluralCategory]]
  5. localepluralRules.[[Locale]]
  6. typepluralRules.[[Type]]
  7. notationpluralRules.[[Notation]]
  8. compactDisplaypluralRules.[[CompactDisplay]]
  9. 返回 PluralRuleSelectRange(locale, type, notation, compactDisplay, xResult.[[PluralCategory]], yResult.[[PluralCategory]])。

18 RelativeTimeFormat 对象

18.1 Intl.RelativeTimeFormat 构造函数

Intl.RelativeTimeFormat 构造函数:

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

Intl 对象的所有服务构造函数属性共有的行为在 9.1 中指定。

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

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

  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. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  6. localeresolvedLocale.[[Locale]]
  7. relativeTimeFormat.[[Locale]] 设为 locale
  8. relativeTimeFormat.[[LocaleData]] 设为 resolvedLocale.[[LocaleData]]
  9. relativeTimeFormat.[[NumberingSystem]] 设为 resolvedLocale.[[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 ] )

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

  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" } »。

Note 1
Unicode 技术标准 #35 第 1 部分 Core,第 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 结果,其值是不作为模板处理的字面 String。
  • [[LocaleData]] 的任一语言环境字段的 "nu" 字段值所对应的 List 不得包含值 "native""traditio""finance"
Note 2
建议实现使用 Common Locale Data Repository 提供的语言环境数据(可在 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. Table 33 的每一行(表头行除外),按表格顺序执行
    1. propertyKey 为当前行的 Property 值。
    2. valuerelativeTimeFormat 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 断言:value 不是 undefined
    4. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  5. 返回 options
Table 33: RelativeTimeFormat 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[Style]] "style"
[[Numeric]] "numeric"
[[NumberingSystem]] "numberingSystem"

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

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

  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 )

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

  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% 属性的初始值是 String 值 "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]] 是一个 String 值,包含用于格式化的本地化所用语言环境的语言标签
  • [[LocaleData]] 是一个 Record,表示实现可用于格式化的数据。它是 %Intl.RelativeTimeFormat%.[[LocaleData]] 中某个条目的值,该条目与 [[Locale]] 的值或其某个前缀相关联。
  • [[Style]] 是 String 值 "long""short""narrow" 之一,用于标识所使用的相对时间格式样式。
  • [[Numeric]] 是 String 值 "always""auto" 之一,用于标识是否始终使用数值描述,或仅在没有更具体版本可用时才使用(例如,"1 day ago" 与 "yesterday")。
  • [[NumberFormat]] 是一个用于格式化的 Intl.NumberFormat 对象。
  • [[NumberingSystem]] 是一个 String 值,表示用于格式化的 Unicode Number System Identifier
  • [[PluralRules]] 是一个用于格式化的 Intl.PluralRules 对象。

18.5 RelativeTimeFormat 对象的抽象操作

18.5.1 SingularRelativeTimeUnit ( unit )

The abstract operation SingularRelativeTimeUnit takes argument unit (一个 String) and returns 包含 String 的正常完成或抛出完成. It performs the following steps when called:

  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 )

The abstract operation PartitionRelativeTimePattern takes arguments relativeTimeFormat (一个 Intl.RelativeTimeFormat), value (一个 Number), and unit (一个 String) and returns 包含具有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Unit]](一个 String 或 empty)的 RecordsList 的正常完成,或抛出完成. It performs the following steps when called:

  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. tense"past"
  9. 否则,
    1. tense"future"
  10. tensePatternspatterns.[[<tense>]]。
  11. formattedValuePartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], (value))。
  12. pluralCategoryResolvePlural(relativeTimeFormat.[[PluralRules]], value).[[PluralCategory]]
  13. patterntensePatterns.[[<pluralCategory>]]。
  14. 返回 MakePartsList(pattern, unit, formattedValue)。

18.5.3 MakePartsList ( pattern, unit, parts )

The abstract operation MakePartsList takes arguments pattern (一个 Pattern String), unit (一个 String), and parts (表示一个格式化 Number 的 RecordsList) and returns 具有字段 [[Type]](一个 String)、[[Value]](一个 String)和 [[Unit]](一个 String 或 empty)的 RecordsList. It performs the following steps when called:

  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
Note
示例:
  1. 返回 MakePartsList("AA{0}BB", "hour", « Record { [[Type]]: "integer", [[Value]]: "15" } »)。
将返回一个类似如下的 RecordsList « { [[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 )

The abstract operation FormatRelativeTime takes arguments relativeTimeFormat (一个 Intl.RelativeTimeFormat), value (一个 Number), and unit (一个 String) and returns 包含 String 的正常完成或抛出完成. It performs the following steps when called:

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

18.5.5 FormatRelativeTimeToParts ( relativeTimeFormat, value, unit )

The abstract operation FormatRelativeTimeToParts takes arguments relativeTimeFormat (一个 Intl.RelativeTimeFormat), value (一个 Number), and unit (一个 String) and returns 包含 Array 的正常完成或抛出完成. It performs the following steps when called:

  1. parts 为 ? PartitionRelativeTimePattern(relativeTimeFormat, value, unit)。
  2. result 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. parts 的每个 Record { [[Type]], [[Value]], [[Unit]] } part,执行
    1. partObjOrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! CreateDataPropertyOrThrow(partObj, "type", part.[[Type]])。
    3. 执行 ! CreateDataPropertyOrThrow(partObj, "value", part.[[Value]])。
    4. 如果 part.[[Unit]] 不是 empty,则
      1. 执行 ! CreateDataPropertyOrThrow(partObj, "unit", part.[[Unit]])。
    5. 执行 ! CreateDataPropertyOrThrow(result, ! ToString(𝔽(n)), partObj)。
    6. n 设为 n + 1。
  5. 返回 result

19 Segmenter 对象

19.1 Intl.Segmenter 构造函数

Intl.Segmenter 构造函数:

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

Intl 对象的所有服务构造函数属性共有的行为在 9.1 中指定。

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

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

  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]], locales, options)。
  5. options 设为 optionsResolution.[[Options]]
  6. resolvedLocaleoptionsResolution.[[ResolvedLocale]]
  7. segmenter.[[Locale]] 设为 resolvedLocale.[[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 ] )

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

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

19.2.3 内部槽

[[AvailableLocales]] 内部槽的值是在 9.1 中所述约束内由实现定义的。

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

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

Note
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. Table 34 的每一行(表头行除外),按表格顺序执行
    1. propertyKey 为当前行的 Property 值。
    2. valuesegmenter 的内部槽的值,该内部槽的名称是当前行的 Internal Slot 值。
    3. 断言:value 不是 undefined
    4. 执行 ! CreateDataPropertyOrThrow(options, propertyKey, value)。
  5. 返回 options
Table 34: Segmenter 实例的已解析选项
内部槽 属性
[[Locale]] "locale"
[[SegmenterGranularity]] "granularity"

19.3.3 Intl.Segmenter.prototype.segment ( string )

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

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

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

%Symbol.toStringTag% 属性的初始值是 String 值 "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]] 是一个 String 值,包含用于分词的本地化所用语言环境的语言标签
  • [[SegmenterGranularity]] 是 String 值 "grapheme""word""sentence" 之一,用于标识要分段的文本元素种类。

19.5 Segments 对象

Segments 实例是一个对象,表示某个特定字符串的片段,并受其构造用 Intl.Segmenter 实例的语言环境和选项约束。

19.5.1 CreateSegmentsObject ( segmenter, string )

The abstract operation CreateSegmentsObject takes arguments segmenter (一个 Intl.Segmenter) and string (一个 String) and returns 一个 Segments 实例. It performs the following steps when called:

  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 )

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

  1. segmentsthis 值。
  2. 执行 ? RequireInternalSlot(segments, [[SegmentsSegmenter]])。
  3. segmentersegments.[[SegmentsSegmenter]]
  4. stringsegments.[[SegmentsString]]
  5. lengthstring 的长度。
  6. n 为 ? ToIntegerOrInfinity(index)。
  7. 如果 n < 0 或 nlength,返回 undefined
  8. startIndexFindBoundary(segmenter, string, n, before)。
  9. endIndexFindBoundary(segmenter, string, n, after)。
  10. 返回 CreateSegmentDataObject(segmenter, string, startIndex, endIndex)。

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

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

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

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

19.5.3 Segments 实例的属性

Segments 实例是从 %IntlSegmentsPrototype% 继承属性的普通对象。

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

Segments 实例具有一个 [[SegmentsString]] 内部槽,引用其暴露片段的 String 值。

19.6 Segment Iterator 对象

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

19.6.1 CreateSegmentIterator ( segmenter, string )

The abstract operation CreateSegmentIterator takes arguments segmenter (一个 Intl.Segmenter) and string (一个 String) and returns 一个 Segment Iterator. It performs the following steps when called:

  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 ( )

next 方法在 Segment Iterator 实例上调用,用于将其向前推进一个片段,并返回一个 IteratorResult 对象,该对象要么描述新片段,要么声明迭代完成。执行以下步骤:

  1. iteratorthis 值。
  2. 执行 ? RequireInternalSlot(iterator, [[IteratingSegmenter]])。
  3. segmenteriterator.[[IteratingSegmenter]]
  4. stringiterator.[[IteratedString]]
  5. startIndexiterator.[[IteratedStringNextSegmentCodeUnitIndex]]
  6. lengthstring 的长度。
  7. 如果 startIndexlength,则
    1. 返回 CreateIteratorResultObject(undefined, true)。
  8. endIndexFindBoundary(segmenter, string, startIndex, after)。
  9. iterator.[[IteratedStringNextSegmentCodeUnitIndex]] 设为 endIndex
  10. segmentDataCreateSegmentDataObject(segmenter, string, startIndex, endIndex)。
  11. 返回 CreateIteratorResultObject(segmentData, false)。

19.6.2.2 %IntlSegmentIteratorPrototype% [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值是 String 值 "Segmenter String Iterator"

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

19.6.3 Segment Iterator 实例的属性

Segment Iterator 实例是从 %SegmentIteratorPrototype% 继承属性的普通对象。Segment Iterator 实例最初以 Table 35 中描述的内部槽创建。

Table 35: Segment Iterator 实例的内部槽
内部槽 描述
[[IteratingSegmenter]] 用于迭代的 Intl.Segmenter 实例。
[[IteratedString]] 正在被迭代的 String 值。
[[IteratedStringNextSegmentCodeUnitIndex]] 正在被迭代的 String 值中下一个片段起始处的码元索引。

19.7 Segment Data 对象

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

19.7.1 CreateSegmentDataObject ( segmenter, string, startIndex, endIndex )

The abstract operation CreateSegmentDataObject takes arguments segmenter (一个 Intl.Segmenter), string (一个 String), startIndex (一个非负整数), and endIndex (一个非负整数) and returns 一个 Segment Data 对象. It performs the following steps when called:

  1. lengthstring 的长度。
  2. 断言:endIndexlength
  3. 断言:startIndex < endIndex
  4. resultOrdinaryObjectCreate(%Object.prototype%)。
  5. segmentstringstartIndexendIndex 的子字符串。
  6. 执行 ! CreateDataPropertyOrThrow(result, "segment", segment)。
  7. 执行 ! CreateDataPropertyOrThrow(result, "index", 𝔽(startIndex))。
  8. 执行 ! CreateDataPropertyOrThrow(result, "input", string)。
  9. granularitysegmenter.[[SegmenterGranularity]]
  10. 如果 granularity"word",则
    1. isWordLike 为一个 Boolean,指示 string 中的 segment 根据语言环境 segmenter.[[Locale]] 是否“类似单词”。
    2. 执行 ! CreateDataPropertyOrThrow(result, "isWordLike", isWordLike)。
  11. 返回 result
Note
片段是否“类似单词”取决于实现,并且建议实现使用语言环境敏感的定制。一般而言,仅由空格和/或标点组成的片段(例如 ICU [International Components for Unicode,文档见 https://unicode-org.github.io/icu-docs/] 中以 "WORD_NONE" 边界终止的那些片段)不被认为是“类似单词”的。

19.8 Segmenter 对象的抽象操作

19.8.1 FindBoundary ( segmenter, string, startIndex, direction )

The abstract operation FindBoundary takes arguments segmenter (一个 Intl.Segmenter), string (一个 String), startIndex (一个非负整数), and direction (beforeafter) and returns 一个非负整数. It performs the following steps when called:

  1. lengthstring 的长度。
  2. 断言:startIndex < length
  3. localesegmenter.[[Locale]]
  4. granularitysegmenter.[[SegmenterGranularity]]
  5. 如果 directionbefore,则
    1. 使用语言环境 locale 和文本元素粒度 granularity,在 string 中搜索最后一个分段边界,该边界前面最多有从开头起 startIndex 个码元。
    2. 如果找到边界,则返回 string 中在其之前的码元数量。
    3. 返回 0。
  6. 断言:directionafter
  7. 使用语言环境 locale 和文本元素粒度 granularity,在 string 中搜索第一个位于索引 startIndex 处码元之后的分段边界。
  8. 如果找到边界,则返回 string 中在其之前的码元数量。
  9. 返回 length
Note
边界确定取决于实现,但通用默认算法在 Unicode Standard Annex #29 中指定。建议实现使用语言环境敏感的定制,例如 Common Locale Data Repository 提供的那些定制(可在 https://cldr.unicode.org 获得)。

20 ECMAScript 语言规范的 Locale 敏感函数

ECMA-262 描述了若干 locale 敏感函数。实现本规范的 ECMAScript 实现应按此处描述实现这些函数。

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

20.1 String 原型对象的属性

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

此定义取代 ECMA-26222.1.3.12 中提供的定义。

localeCompare 方法以实参 that 和可选实参 localesoptions 调用时,执行以下步骤:

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

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

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

20.1.2 String.prototype.toLocaleLowerCase ( [ locales ] )

此定义取代 ECMA-26222.1.3.26 中提供的定义。

此函数将一个 String 值解释为码点序列,如 ECMA-2626.1.4 中所述。执行以下步骤:

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

20.1.2.1 TransformCase ( string, locales, targetCase )

The abstract operation TransformCase takes arguments string (一个 String), locales (一个 ECMAScript 语言值), and targetCase (lowerupper). 它将 string 解释为 UTF-16 编码码点序列,如 ECMA-2626.1.4 中所述,并将 ILD 转换为 targetCase 的结果作为新的 String 值返回。 It performs the following steps when called:

  1. requestedLocales 为 ? CanonicalizeLocaleList(locales)。
  2. 如果 requestedLocales 不是空 List,则
    1. requestedLocalerequestedLocales[0]。
  3. 否则,
    1. requestedLocaleDefaultLocale()。
  4. availableLocales 为一个 Available Locales List,其中包含 Unicode Character Database 具有语言敏感大小写映射的语言标签。如果实现支持额外的 locale 敏感大小写映射,availableLocales 也应包含其对应的语言标签
  5. matchLookupMatchingLocaleByPrefix(availableLocales, « requestedLocale »)。
  6. 如果 match 不是 undefined,则令 localematch.[[locale]];否则令 locale"und"
  7. codePointsStringToCodePoints(string)。
  8. 如果 targetCaselower,则
    1. newCodePoints 为一个 List,其元素是根据使用 locale 的实现派生算法或 Unicode Default Case Conversion 算法对 codePoints 执行小写转换的结果。
  9. 否则,
    1. 断言:targetCaseupper
    2. newCodePoints 为一个 List,其元素是根据使用 locale 的实现派生算法或 Unicode Default Case Conversion 算法对 codePoints 执行大写转换的结果。
  10. 返回 CodePointsToString(newCodePoints)。

码点映射可以根据 Unicode Standard 的 Default Case Conversion Algorithms 的定制版本派生。实现可以使用 Unicode Character Database 的 SpecialCasing.txt 文件和/或 CLDR 中定义的 locale 敏感定制,和/或任何其他自定义定制。无论是否定制,符合规范的实现的大小写转换算法在给定相同输入码点、locale 和目标大小写时,必须始终产生相同结果。

Note
某些码点的大小写映射可能产生多个码点,因此结果长度可能与输入长度不同。由于 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. thisValue 为 ? RequireObjectCoercible(this value)。
  2. string 为 ? ToString(thisValue)。
  3. 返回 ? TransformCase(string, locales, upper)。
Note
toLocaleUpperCase 函数有意设计为泛型;它不要求其 this 值是 String 对象。因此,它可以转移到其他类型的对象上作为方法使用。

20.2 Number 原型对象的属性

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

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

此定义取代 ECMA-26221.1.3.4 中提供的定义。

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

  1. x 为 ? ThisNumberValue(this value)。
  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 中提供的定义。

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

  1. x 为 ? ThisBigIntValue(this value)。
  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 中提供的定义。

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

  1. dateObjthis 值。
  2. 执行 ? RequireInternalSlot(dateObj, [[DateValue]])。
  3. xdateObj.[[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 ] ] ) 中提供的定义。

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

  1. dateObjthis 值。
  2. 执行 ? RequireInternalSlot(dateObj, [[DateValue]])。
  3. xdateObj.[[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 ] ] ) 中提供的定义。

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

  1. dateObjthis 值。
  2. 执行 ? RequireInternalSlot(dateObj, [[DateValue]])。
  3. xdateObj.[[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 ] ] ) 中提供的定义。

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

  1. array 为 ? ToObject(this value)。
  2. length 为 ? LengthOfArrayLike(array)。
  3. separator 为适用于宿主环境当前 locale 的实现定义列表分隔符 String 值(例如 ", ")。
  4. result 为空 String。
  5. k 为 0。
  6. 重复,当 k < length 时,
    1. 如果 k > 0,则
      1. result 设置为 resultseparator 的字符串拼接。
    2. element 为 ? Get(array, ! ToString(𝔽(k)))。
    3. 如果 element 既不是 undefined 也不是 null,则
      1. elementString 为 ? ToString(? Invoke(element, "toLocaleString", « locales, options »))。
      2. result 设置为 resultelementString 的字符串拼接。
    4. k 设置为 k + 1。
  7. 返回 result
Note 1
此算法的步骤镜像了 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) 中执行的步骤,区别是 Invoke(nextElement, "toLocaleString") 现在以 localesoptions 作为实参。
Note 2
数组的元素使用它们的 toLocaleString 方法转换为 String,然后这些 String 被拼接起来,并由出现的实现定义 locale 敏感分隔符 String 分隔。此函数类似于 toString,但它旨在产生与宿主环境当前 locale 约定相对应的 locale 敏感结果。
Note 3
toLocaleString 函数有意设计为泛型;它不要求其 this 值是 Array 对象。因此,它可以转移到其他类型的对象上作为方法使用。

Annex A (informative) 实现依赖行为

本规范中的以下方面是实现依赖的:

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

Annex C (informative)

本规范在GitHub上以一种名为Ecmarkup的纯文本源格式编写。Ecmarkup 是一种 HTML 和 Markdown 方言,为以纯文本编写 ECMAScript 规范并处理规范为完整 HTML 渲染提供了框架和工具集,遵循本文件的编辑惯例。Ecmarkup 构建并集成了多种其他格式和技术,包括用于定义语法的Grammarkdown和用于编写算法步骤的Ecmarkdown。本规范的 PDF 渲染使用打印样式表,利用 CSS Paged Media 规范,并通过PrinceXML进行转换。

本规范的早期版本使用 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.