Stage 3 Draft / May 20, 2019

Intl.Locale

1Locale Objects

1.1The Intl.Locale Constructor

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

1.1.1ApplyOptionsToTag( 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 production, 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 production, throw a RangeError exception.
  9. Set tag to CanonicalizeLanguageTag(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 replaced by the string language.
  11. If script is not undefined, then
    1. If tag does not contain a unicode_script_subtag production, then
      1. Set tag to the concatenation of the unicode_language_subtag production 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 replaced by the string script.
  12. If region is not undefined, then
    1. If tag does not contain a unicode_region_subtag production, then
      1. Set tag to the concatenation of the unicode_language_subtag production of tag, the substring corresponding to the "-" unicode_script_subtag production 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 replaced by the string region.
  13. Return CanonicalizeLanguageTag(tag).

1.1.2ApplyUnicodeExtensionToTag( 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 the canonicalized Unicode BCP 47 U Extension based on attributes and keywords as defined in UTS #35 section 3.6.
  9. If newExtension is not the empty String, then
    1. Let locale be ? InsertUnicodeExtension(locale, newExtension).
  10. Set result.[[locale]] to locale.
  11. Return result.

1.1.3UnicodeExtensionComponents( 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.4InsertUnicodeExtension( locale, extension )

The InsertUnicodeExtension 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 ! CanonicalizeLanguageTag(locale).

1.1.5Intl.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 (3*8alphanum) *("-" (3*8alphanum)) sequence, 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 (3*8alphanum) *("-" (3*8alphanum)) sequence, 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 (3*8alphanum) *("-" (3*8alphanum)) sequence, 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. Set locale.[[Numeric]] to ! SameValue(r.[[kn]], "true").
  37. Set locale.[[NumberingSystem]] to r.[[nu]].
  38. Return locale.

1.2Properties of the Intl.Locale Constructor

The Intl.Locale constructor has the following properties:

1.2.1Intl.Locale.prototype

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

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

1.2.2Internal 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.3Properties 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.1Intl.Locale.prototype.constructor

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

1.3.2Intl.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.3Intl.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.4Intl.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.5Intl.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.6get 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. If locale does not match the unicode_locale_id production, return locale.
  5. Return the substring of locale corresponding to the language ["-" script] ["-" region] *("-" variant) subsequence of the unicode_language_id grammar.

1.3.7get 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.8get 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.9get 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.10get 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.11get 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.12get 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.13get 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.

1.3.14get 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 locale does not contain the ["-" script] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_script_subtag production.

1.3.15get 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 locale does not contain the ["-" region] sequence, return undefined.
  6. Return the substring of locale corresponding to the unicode_region_subtag production.

2Modified algorithms

2.1CanonicalizeLocaleList ( 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 CanonicalizeLanguageTag(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.

ACopyright & Software License

Copyright Notice

© 2019 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.