Stage 3 Draft / February 14, 2020

Intl.Locale

1 Locale Objects

1.1 The Intl.Locale Constructor

The Locale constructor is a standard built-in property of the Intl object.

1.1.1 ApplyOptionsToTag( tag, options )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Assert: Type(tag) is String.
  2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
  3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
  4. If language is not undefined, then
    1. If language does not match the unicode_language_subtag production, throw a RangeError exception.
  5. Let script be ? GetOption(options, "script", "string", undefined, undefined).
  6. If script is not undefined, then
    1. If script does not match the unicode_script_subtag, throw a RangeError exception.
  7. Let region be ? GetOption(options, "region", "string", undefined, undefined).
  8. If region is not undefined, then
    1. If region does not match the unicode_region_subtag, throw a RangeError exception.
  9. Set tag to CanonicalizeUnicodeLocaleId(tag).
  10. If language is not undefined,
    1. Assert: tag matches the unicode_locale_id production.
    2. Set tag to tag with the substring corresponding to the unicode_language_subtag production of the unicode_language_id replaced by the string language.
  11. If script is not undefined, then
    1. If tag does not contain a unicode_script_subtag production of the unicode_language_id, then
      1. Set tag to the concatenation of the unicode_language_subtag production of the unicode_languge_id of tag, "-", script, and the rest of tag.
    2. Else,
      1. Set tag to tag with the substring corresponding to the unicode_script_subtag production of the unicode_language_id replaced by the string script.
  12. If region is not undefined, then
    1. If tag does not contain a unicode_region_subtag production of the unicode_language_id, then
      1. Set tag to the concatenation of the unicode_language_subtag production of the unicode_language_id of tag, the substring corresponding to the "-" unicode_script_subtag production of the unicode_language_id if present, "-", region, and the rest of tag.
    2. Else,
      1. Set tag to tag with the substring corresponding to the unicode_region_subtag production of the unicode_language_id replaced by the string region.
  13. Return CanonicalizeUnicodeLocaleId(tag).

1.1.2 ApplyUnicodeExtensionToTag( tag, options, relevantExtensionKeys )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Assert: Type(tag) is String.
  2. Assert: tag matches the unicode_locale_id production.
  3. If tag contains a substring that is a Unicode locale extension sequence, then
    1. Let extension be the String value consisting of the first substring of tag that is a Unicode locale extension sequence.
    2. Let components be ! UnicodeExtensionComponents(extension).
    3. Let attributes be components.[[Attributes]].
    4. Let keywords be components.[[Keywords]].
  4. Else,
    1. Let attributes be the empty List.
    2. Let keywords be the empty List.
  5. Let result be a new Record.
  6. Repeat for each element key of relevantExtensionKeys in List order,
    1. Let value be undefined.
    2. If keywords contains an element whose [[Key]] is the same as key, then
      1. Let entry be the element of keywords whose [[Key]] is the same as key.
      2. Let value be entry.[[Value]].
    3. Else
      1. Let entry be empty.
    4. Assert: options has a field [[<key>]].
    5. Let optionsValue be options.[[<key>]].
    6. If optionsValue is not undefined, then
      1. Assert: Type(optionsValue) is String.
      2. Let value be optionsValue.
      3. If entry is not empty, then
        1. Set entry.[[Value]] to value.
      4. Else,
        1. Append the Record{[[Key]]: key, [[Value]]: value} to keywords.
    7. Set result.[[<key>]] to value.
  7. Let locale be the String value that is tag with all Unicode locale extension sequences removed.
  8. Let newExtension be a Unicode BCP 47 U Extension based on attributes and keywords.
  9. If newExtension is not the empty String, then
    1. Let locale be ! InsertUnicodeExtensionAndCanonicalize(locale, newExtension).
  10. Set result.[[locale]] to locale.
  11. Return result.

1.1.3 UnicodeExtensionComponents( extension )

The UnicodeExtensionComponents abstract operation returns the attributes and keywords from extension, which must be a Unicode locale extension sequence. If an attribute or a keyword occurs multiple times in extension, only the first occurence is returned. The following steps are taken:

  1. Let attributes be the empty List.
  2. Let keywords be the empty List.
  3. Let isKeyword be false.
  4. Let size be the number of elements in extension.
  5. Let k be 3.
  6. Repeat, while k < size
    1. Let e be ! Call(%StringProto_indexOf%, extension, « "-", k »).
    2. If e = -1, let len be size - k; else let len be e - k.
    3. Let subtag be the String value equal to the substring of extension consisting of the code units at indices k (inclusive) through k + len (exclusive).
    4. If isKeyword is false, then
      1. If len ≠ 2 and subtag is not an element of attributes, then
        1. Append subtag to attributes.
    5. Else,
      1. If len = 2, then
        1. If keywords does not contain an element whose [[Key]] is the same as key, then
          1. Append the Record{[[Key]]: key, [[Value]]: value} to keywords.
      2. Else,
        1. If value is not the empty String, then
          1. Let value be the string-concatenation of value and "-".
        2. Let value be the string-concatenation of value and subtag.
    6. If len = 2, then
      1. Let isKeyword be true.
      2. Let key be subtag.
      3. Let value be the empty String.
    7. Let k be k + len + 1.
  7. If isKeyword is true, then
    1. If keywords does not contain an element whose [[Key]] is the same as key, then
      1. Append the Record{[[Key]]: key, [[Value]]: value} to keywords.
  8. Return the Record{[[Attributes]]: attributes, [[Keywords]]: keywords}.

1.1.4 InsertUnicodeExtensionAndCanonicalize( locale, extension )

The InsertUnicodeExtensionAndCanonicalize abstract operation inserts extension, which must be a Unicode locale extension sequence, into locale, which must be a String value with a structurally valid and canonicalized BCP 47 language tag. The following steps are taken:

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar.

  1. Assert: locale does not contain a substring that is a Unicode locale extension sequence.
  2. Assert: extension is a Unicode extension sequence.
  3. Assert: tag matches the unicode_locale_id production.
  4. Let privateIndex be ! Call(%StringProto_indexOf%, locale, « "-x-" »).
  5. If privateIndex = -1, then
    1. Let locale be the concatenation of locale and extension.
  6. Else,
    1. Let preExtension be the substring of locale from position 0, inclusive, to position privateIndex, exclusive.
    2. Let postExtension be the substring of locale from position privateIndex to the end of the string.
    3. Let locale be the string-concatenation of preExtension, extension, and postExtension.
  7. Assert: IsStructurallyValidLanguageTag(locale) is true.
  8. Return ! CanonicalizeUnicodeLocaleId(locale).

1.1.5 Intl.Locale( tag [, options] )

The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. When the Intl.Locale function is called with an argument tag and an optional argument options, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let relevantExtensionKeys be %Locale%.[[RelevantExtensionKeys]].
  3. Let internalSlotsList be « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[HourCycle]], [[NumberingSystem]] ».
  4. If relevantExtensionKeys contains "kf", then
    1. Append [[CaseFirst]] as the last element of internalSlotsList.
  5. If relevantExtensionKeys contains "kn", then
    1. Append [[Numeric]] as the last element of internalSlotsList.
  6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, %LocalePrototype%, internalSlotsList).
  7. If Type(tag) is not String or Object, throw a TypeError exception.
  8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal slot, then
    1. Let tag be tag.[[Locale]].
  9. Else,
    1. Let tag be ? ToString(tag).
  10. If options is undefined, then
    1. Let options be ! ObjectCreate(null).
  11. Else
    1. Let options be ? ToObject(options).
  12. Set tag to ? ApplyOptionsToTag(tag, options).
  13. Let opt be a new Record.
  14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
  15. If calendar is not undefined, then
    1. If calendar does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  16. Set opt.[[ca]] to calendar.
  17. Let collation be ? GetOption(options, "collation", "string", undefined, undefined).
  18. If collation is not undefined, then
    1. If collation does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  19. Set opt.[[co]] to collation.
  20. Let hc be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
  21. Set opt.[[hc]] to hc.
  22. Let kf be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined).
  23. Set opt.[[kf]] to kf.
  24. Let kn be ? GetOption(options, "numeric", "boolean", undefined, undefined).
  25. If kn is not undefined, set kn to ! ToString(kn).
  26. Set opt.[[kn]] to kn.
  27. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
  28. If numberingSystem is not undefined, then
    1. If numberingSystem does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
  29. Set opt.[[nu]] to numberingSystem.
  30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
  31. Set locale.[[Locale]] to r.[[locale]].
  32. Set locale.[[Calendar]] to r.[[ca]].
  33. Set locale.[[Collation]] to r.[[co]].
  34. Set locale.[[HourCycle]] to r.[[hc]].
  35. If relevantExtensionKeys contains "kf", then
    1. Set locale.[[CaseFirst]] to r.[[kf]].
  36. If relevantExtensionKeys contains "kn", then
    1. If ! SameValue(r.[[kn]], "true") is true or ! SameValue(r.[[kn]], "") is true, then
      1. Let numeric be true.
    2. Else,
      1. Let numeric be false.
    3. Set locale.[[Numeric]] to numeric.
  37. Set locale.[[NumberingSystem]] to r.[[nu]].
  38. Return locale.

1.2 Properties of the Intl.Locale Constructor

The Intl.Locale constructor has the following properties:

1.2.1 Intl.Locale.prototype

The value of Intl.Locale.prototype is %LocalePrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

1.2.2 Internal slots

The value of the [[RelevantExtensionKeys]] internal slot is « "ca", "co", "hc", "kf", "kn", "nu" ». If %Collator%.[[RelevantExtensionKeys]] does not contain "kf", then remove "kf" from %Locale%.[[RelevantExtensionKeys]]. If %Collator%.[[RelevantExtensionKeys]] does not contain "kn", then remove "kn" from %Locale%.[[RelevantExtensionKeys]].

1.3 Properties of the Intl.Locale Prototype Object

The Intl.Locale prototype object is itself an ordinary object. %LocalePrototype% is not an Intl.Locale instance and does not have an [[InitializedLocale]] internal slot or any of the other internal slots of Intl.Locale instance objects.

1.3.1 Intl.Locale.prototype.constructor

The initial value of Intl.Locale.prototype.constructor is %Locale%.

1.3.2 Intl.Locale.prototype[ @@toStringTag ]

The initial value of the @@toStringTag property is the string value "Intl.Locale".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

1.3.3 Intl.Locale.prototype.maximize ()

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
  4. Return ! Construct(%Locale%, maximal).

1.3.4 Intl.Locale.prototype.minimize ()

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
  4. Return ! Construct(%Locale%, minimal).

1.3.5 Intl.Locale.prototype.toString ()

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[Locale]].

1.3.6 get Intl.Locale.prototype.baseName

Intl.Locale.prototype.baseName is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let locale be loc.[[Locale]].
  4. Return the substring of locale corresponding to the unicode_language_id production.

1.3.7 get Intl.Locale.prototype.calendar

Intl.Locale.prototype.calendar is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[Calendar]].

1.3.8 get Intl.Locale.prototype.caseFirst

This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kf".

Intl.Locale.prototype.caseFirst is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[CaseFirst]].

1.3.9 get Intl.Locale.prototype.collation

Intl.Locale.prototype.collation is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[Collation]].

1.3.10 get Intl.Locale.prototype.hourCycle

Intl.Locale.prototype.hourCycle is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[HourCycle]].

1.3.11 get Intl.Locale.prototype.numeric

This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kn".

Intl.Locale.prototype.numeric is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[Numeric]].

1.3.12 get Intl.Locale.prototype.numberingSystem

Intl.Locale.prototype.numberingSystem is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Return loc.[[NumberingSystem]].

1.3.13 get Intl.Locale.prototype.language

Intl.Locale.prototype.language is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. Return the substring of locale corresponding to the unicode_language_subtag production of the unicode_language_id.

1.3.14 get Intl.Locale.prototype.script

Intl.Locale.prototype.script is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. If the unicode_language_id production of locale does not contain the ["-" unicode_script_subtag] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_script_subtag production of the unicode_language_id.

1.3.15 get Intl.Locale.prototype.region

Intl.Locale.prototype.region is an accessor property whose set accessor function is undefined. The following algorithm refers to UTS 35's Unicode Language and Locale Identifiers grammar. Its get accessor function performs the following steps:

  1. Let loc be the this value.
  2. If Type(loc) is not Object or loc does not have an [[InitializedLocale]] internal slot, then
    1. Throw a TypeError exception.
  3. Let locale be loc.[[Locale]].
  4. Assert: locale matches the unicode_locale_id production.
  5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.

2 Modified algorithms

2.1 CanonicalizeLanguageTagCanonicalizeUnicodeLocaleId ( locale )

The CanonicalizeLanguageTagCanonicalizeUnicodeLocaleId abstract operation returns the canonical and case-regularized form of the locale argument (which must be a String value that is a structurally valid Unicode BCP 47 Locale Identifier as verified by the IsStructurallyValidLanguageTag abstract operation). A conforming implementation shall take the steps specified in the “BCP 47 Language Tag to Unicode BCP 47 Locale Identifier” algorithm, from Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion. The following steps are taken:

  1. Let localeId be the string locale after performing the steps specified in the “BCP 47 Language Tag to Unicode BCP 47 Locale Identifier” algorithm, from Unicode Technical Standard #35 LDML § 3.3.1 BCP 47 Language Tag Conversion, on it. (The result is a Unicode BCP 47 locale identifier, in canonical syntax but not necessarily in canonical form.)
  2. Let localeId be the string localeId after performing the algorithm to transform it to canonical form. (The result is a Unicode BCP 47 locale identifier, in both canonical syntax and canonical form.)
  3. If localeId contains a substring extension that is a Unicode locale extension sequence, then
    1. Let components be ! UnicodeExtensionComponents(extension).
    2. Let attributes be components.[[Attributes]].
    3. Let keywords be components.[[Keywords]].
    4. Let newExtension be "u".
    5. For each element attr of attributes in List order, do
      1. Append "-" to newExtension.
      2. Append attr to newExtension.
    6. For each element keyword of keywords in List order, do
      1. Append "-" to newExtension.
      2. Append keyword.[[Key]] to newExtension.
      3. If keyword.[[Value]] is not the empty String, then
        1. Append "-" to newExtension.
        2. Append keyword.[[Value]] to newExtension.
    7. Assert: newExtension is not equal to "u".
    8. Let localeId be localeId with the substring corresponding to extension replaced by the string newExtension.
  4. Return localeId.
Note
The third step of this algorithm ensures that a Unicode locale extension sequence in the returned language tag contains:
  • only the first instance of any attribute duplicated in the input, and
  • only the first keyword for a given key in the input.

2.2 CanonicalizeLocaleList ( locales )

The abstract operation CanonicalizeLocaleList takes the following steps:

  1. If locales is undefined, then
    1. Return a new empty List.
  2. Let seen be a new empty List.
  3. If Type(locales) is String or locales has an [[InitializedLocale]] internal slot, then
    1. Let O be CreateArrayFromListlocales »).
  4. Else,
    1. Let O be ? ToObject(locales).
  5. Let len be ? ToLength(? Get(O, "length")).
  6. Let k be 0.
  7. Repeat, while k < len
    1. Let Pk be ToString(k).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. If Type(kValue) is not String or Object, throw a TypeError exception.
      3. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then
        1. Let tag be kValue.[[Locale]].
      4. Else,
        1. Let tag be ? ToString(kValue).
      5. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
      6. Let canonicalizedTag be CanonicalizeLanguageTagCanonicalizeUnicodeLocaleId(tag).
      7. If canonicalizedTag is not an element of seen, append canonicalizedTag as the last element of seen.
    4. Increase k by 1.
  8. Return seen.
Editor's Note
When integrating into the main specification, the Intl.Locale object handling in this algorithm may be refactored to turn all strings into Intl.Locale instances, moving logic from ResolveLocale. This will be an editorial cleanup.

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

The ResolveLocale abstract operation compares a BCP 47 language priority list requestedLocales against the locales in availableLocales and determines the best available language to meet the request. availableLocales, requestedLocales, and relevantExtensionKeys must be provided as List values, options and localeData as Records.

The following steps are taken:

  1. Let matcher be options.[[localeMatcher]].
  2. If matcher is "lookup", then
    1. Let r be LookupMatcher(availableLocales, requestedLocales).
  3. Else,
    1. Let r be BestFitMatcher(availableLocales, requestedLocales).
  4. Let foundLocale be r.[[locale]].
  5. Let result be a new Record.
  6. Set result.[[dataLocale]] to foundLocale.
  7. Let supportedExtension be "-u".
  8. For each element key of relevantExtensionKeys in List order, do
    1. Let foundLocaleData be localeData.[[<foundLocale>]].
    2. Assert: Type(foundLocaleData) is Record.
    3. Let keyLocaleData be foundLocaleData.[[<key>]].
    4. Assert: Type(keyLocaleData) is List.
    5. Let value be keyLocaleData[0].
    6. Assert: Type(value) is either String or Null.
    7. Let supportedExtensionAddition be "".
    8. If r has an [[extension]] field, then
      1. Let requestedValue be UnicodeExtensionValue(r.[[extension]], key).
      2. If requestedValue is not undefined, then
        1. If requestedValue is not the empty String, then
          1. If keyLocaleData contains requestedValue, then
            1. Let value be requestedValue.
            2. Let supportedExtensionAddition be the string-concatenation of "-", key, "-", and value.
        2. Else if keyLocaleData contains "true", then
          1. Let value be "true".
          2. Let supportedExtensionAddition be the string-concatenation of "-" and key.
    9. If options has a field [[<key>]], then
      1. Let optionsValue be options.[[<key>]].
      2. Assert: Type(optionsValue) is either String, Undefined, or Null.
      3. If keyLocaleData contains optionsValue, then
        1. If SameValue(optionsValue, value) is false, then
          1. Let value be optionsValue.
          2. Let supportedExtensionAddition be "".
    10. Set result.[[<key>]] to value.
    11. Append supportedExtensionAddition to supportedExtension.
  9. If the number of elements in supportedExtension is greater than 2, then
    1. Let privateIndex be Call(%StringProto_indexOf%, foundLocale, « "-x-" »).
    2. If privateIndex = -1, then
      1. Let foundLocale be the string-concatenation of foundLocale and supportedExtension.
    3. Else,
      1. Let preExtension be the substring of foundLocale from position 0, inclusive, to position privateIndex, exclusive.
      2. Let postExtension be the substring of foundLocale from position privateIndex to the end of the string.
      3. Let foundLocale be the string-concatenation of preExtension, supportedExtension, and postExtension.
    4. Assert: IsStructurallyValidLanguageTag(foundLocale) is true.
    5. Let foundLocale be CanonicalizeLanguageTagCanonicalizeUnicodeLocaleId(foundLocale).
  10. Set result.[[locale]] to foundLocale.
  11. Return result.
Note
Non-normative summary: Two algorithms are available to match the locales: the Lookup algorithm described in RFC 4647 section 3.4, and an implementation dependent best-fit algorithm. Independent of the locale matching algorithm, options specified through Unicode locale extension sequences are negotiated separately, taking the caller's relevant extension keys and locale data as well as client-provided options into consideration. The abstract operation returns a record with a [[locale]] field whose value is the language tag of the selected locale, and fields for each key in relevantExtensionKeys providing the selected value for that key.

A Copyright & Software License

Copyright Notice

© 2020 Mozilla, Ecma International

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.