Stage 3 Draft / December 18, 2024

Intl Locale Info Proposal

Introduction

This proposal exposes Locale information, such as week data (first day in a week, weekend start day, weekend end day, minimun day in the first week), hour cycle used in the locale, measurement system used in the locale. See the README for more context.

1 Locale Objects

1.1 Abstract Operations for Locale Objects

1.1.1 CreateArrayFromListOrRestricted ( list, restricted )

The abstract operation CreateArrayFromListOrRestricted takes arguments list (a List of ECMAScript language values) and restricted (an ECMAScript language value*) and returns an Array. It performs the following steps when called:

  1. If restricted is not undefined, then
    1. Set list to « restricted ».
  2. Return CreateArrayFromList( list ).

1.1.2 CalendarsOfLocale ( loc )

The abstract operation CalendarsOfLocale takes argument loc (an Intl.Locale) and returns an Array. It performs the following steps when called:

  1. Let restricted be loc.[[Calendar]].
  2. Let locale be loc.[[Locale]].
  3. Let list be a List of one or more unique calendar types in canonical form (10), sorted in descending preference of those in common use for date and time formatting in locale.
  4. Return CreateArrayFromListOrRestricted( list, restricted ).

1.1.3 CollationsOfLocale ( loc )

The abstract operation CollationsOfLocale takes argument loc (an Intl.Locale) and returns an Array. It performs the following steps when called:

  1. Let restricted be loc.[[Collation]].
  2. Let locale be loc.[[Locale]].
  3. Let list be a List of one or more unique collation types in canonical form (9), of those in common use for string comparison in locale. The values "standard" and "search" must be excluded from list. The list is sorted according to lexicographic code unit order.
  4. Return CreateArrayFromListOrRestricted( list, restricted ).

1.1.4 HourCyclesOfLocale ( loc )

The abstract operation HourCyclesOfLocale takes argument loc (an Intl.Locale) and returns an Array. It performs the following steps when called:

  1. Let restricted be loc.[[HourCycle]].
  2. Let locale be loc.[[Locale]].
  3. Let list be a List of one or more unique hour cycle identifiers, which must be lower case String values indicating either the 12-hour format ("h11", "h12") or the 24-hour format ("h23", "h24"), sorted in descending preference of those in common use for date and time formatting in locale.
  4. Return CreateArrayFromListOrRestricted( list, restricted ).

1.1.5 NumberingSystemsOfLocale ( loc )

The abstract operation NumberingSystemsOfLocale takes argument loc (an Intl.Locale) and returns an Array. It performs the following steps when called:

  1. Let restricted be loc.[[NumberingSystem]].
  2. Let locale be loc.[[Locale]].
  3. Let list be a List of one or more unique numbering system identifiers in canonical form (8), sorted in descending preference of those in common use for formatting numeric values in locale.
  4. Return CreateArrayFromListOrRestricted( list, restricted ).

1.1.6 TimeZonesOfLocale ( loc )

The abstract operation TimeZonesOfLocale takes argument loc (an Intl.Locale) and returns an Array. It performs the following steps when called:

  1. Let region be GetLocaleRegion(loc.[[Locale]]).
  2. Assert: region is not undefined.
  3. Let list be a List of unique canonical time zone identifiers, which must be String values indicating a canonical Zone name of the IANA Time Zone Database, of those in common use in region. The list is empty if no time zones are commonly used in region. The list is sorted according to lexicographic code unit order.
  4. Return CreateArrayFromList( list ).

1.1.7 CharacterDirectionOfLocale ( loc )

The abstract operation CharacterDirectionOfLocale takes argument loc (an Intl.Locale) and returns "ltr" or "rtl". The following algorithm refers to Locale data specified in UTS 35's Layouts Elements. It performs the following steps when called:

  1. Let locale be loc.[[Locale]].
  2. If the default general ordering of characters (characterOrder) within a line in locale is right-to-left, return "rtl".
  3. Return "ltr".
Note
When the direction of default general ordering of characters (characterOrder) within a line in the locale cannot be determined, or is not right-to-left, "ltr" will be retruned.

1.1.8 WeekdayToString ( fw )

The abstract operation WeekdayToString takes argument fw (a String) and returns a String. It performs the following steps when called:

  1. For each row of Table 1, except the header row, in table order, do
    1. Let w be the name given in the Weekday column of the current row.
    2. Let s be the name given in the String column of the current row.
    3. If fw is equal to w, return s.
  2. Return fw.
Table 1: First Day String and Value
Weekday String Value
"0" "sun" 7𝔽
"1" "mon" 1𝔽
"2" "tue" 2𝔽
"3" "wed" 3𝔽
"4" "thu" 4𝔽
"5" "fri" 5𝔽
"6" "sat" 6𝔽
"7" "sun" 7𝔽

1.1.9 StringToWeekdayValue ( fw )

The abstract operation StringToWeekdayValue takes argument fw (a String) and returns an integral Number or undefined. It performs the following steps when called:

  1. For each row of Table 1, except the header row, in table order, do
    1. Let s be the name given in the String column of the current row.
    2. Let v be the name given in the Value column of the current row.
    3. If fw is equal to s, return v.
  2. Return undefined.

1.1.10 WeekInfoOfLocale ( loc )

The abstract operation WeekInfoOfLocale takes argument loc (an Intl.Locale) and returns a Record. The following algorithm refers to Locale data specified in UTS 35's Week Elements. It performs the following steps when called:

  1. Let locale be loc.[[Locale]].
  2. Let r be a Record whose fields are defined by Table 2, with values based on locale.
  3. Let fws be loc.[[FirstDayOfWeek]].
  4. Let fw be StringToWeekdayValue(fws).
  5. If fw is not undefined, then
    1. Set r.[[FirstDay]] to fw.
  6. Return r.
Note
The record's return values are determined by locale, in accordance with the specifications outlined in UTS 35's Week Data and First Day Overrides.
Table 2: WeekInfo Record Fields
Field Name Value Meaning
[[FirstDay]] Integral Number value between 1𝔽 and 7𝔽: 1𝔽 specifies Monday; 2𝔽 specifies Tuesday; 3𝔽 specifies Wednesday; 4𝔽 specifies Thursday; 5𝔽 specifies Friday; 6𝔽 specifies Saturday; and 7𝔽 specifies Sunday. The weekday value indicating which day of the week is considered the 'first' day, for calendar purposes.
[[Weekend]] A List of one or more integral Number values, in ascending order, between 1𝔽 and 7𝔽: 1𝔽 specifies Monday; 2𝔽 specifies Tuesday; 3𝔽 specifies Wednesday; 4𝔽 specifies Thursday; 5𝔽 specifies Friday; 6𝔽 specifies Saturday; and 7𝔽 specifies Sunday. The list of weekday values indicating which days of the week are considered as part of the 'weekend', for calendar purposes. Notice that the number of days in the weekend are different in each locale and may not be contiguous.
[[MinimalDays]] Integral Number value between 1𝔽 and 7𝔽. The minimal days required in the first week of a month or year, for calendar purposes.

1.2 The Intl.Locale Constructor

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

1.2.1 Intl.Locale ( tag [ , options ] )

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 %Intl.Locale%.[[RelevantExtensionKeys]].
  3. Let internalSlotsList be « [[InitializedLocale]], [[Locale]], [[Calendar]], [[Collation]], [[FirstDayOfWeek]], [[HourCycle]], [[NumberingSystem]] ».
  4. If relevantExtensionKeys contains "kf", then
    1. Append [[CaseFirst]] to internalSlotsList.
  5. If relevantExtensionKeys contains "kn", then
    1. Append [[Numeric]] to internalSlotsList.
  6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, "%Intl.Locale.prototype%", internalSlotsList).
  7. If tag is not a String and tag is not an Object, throw a TypeError exception.
  8. If tag is an Object and tag has an [[InitializedLocale]] internal slot, then
    1. Let tag be tag.[[Locale]].
  9. Else,
    1. Let tag be ? ToString(tag).
  10. Set options to ? CoerceOptionsToObject(options).
  11. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
  12. Set tag to CanonicalizeUnicodeLocaleId(tag).
  13. Set tag to ? UpdateLanguageId(tag, options).
  14. Let opt be a new Record.
  15. Let calendar be ? GetOption(options, "calendar", string, empty, undefined).
  16. If calendar is not undefined, then
    1. If calendar cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
  17. Set opt.[[ca]] to calendar.
  18. Let collation be ? GetOption(options, "collation", string, empty, undefined).
  19. If collation is not undefined, then
    1. If collation cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
  20. Set opt.[[co]] to collation.
  21. Let fw be ? GetOption(options, "firstDayOfWeek", string, empty, undefined).
  22. If fw is not undefined, then
    1. Set fw to WeekdayToString(fw).
    2. If fw cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
  23. Set opt.[[fw]] to fw.
  24. Let hc be ? GetOption(options, "hourCycle", string, « "h11", "h12", "h23", "h24" », undefined).
  25. Set opt.[[hc]] to hc.
  26. Let kf be ? GetOption(options, "caseFirst", string, « "upper", "lower", "false" », undefined).
  27. Set opt.[[kf]] to kf.
  28. Let kn be ? GetOption(options, "numeric", boolean, empty, undefined).
  29. If kn is not undefined, set kn to ! ToString(kn).
  30. Set opt.[[kn]] to kn.
  31. Let numberingSystem be ? GetOption(options, "numberingSystem", string, empty, undefined).
  32. If numberingSystem is not undefined, then
    1. If numberingSystem cannot be matched by the type Unicode locale nonterminal, throw a RangeError exception.
  33. Set opt.[[nu]] to numberingSystem.
  34. Let r be MakeLocaleRecord(tag, opt, relevantExtensionKeys).
  35. Set locale.[[Locale]] to r.[[locale]].
  36. Set locale.[[Calendar]] to r.[[ca]].
  37. Set locale.[[Collation]] to r.[[co]].
  38. Set locale.[[FirstDayOfWeek]] to r.[[fw]].
  39. Set locale.[[HourCycle]] to r.[[hc]].
  40. If relevantExtensionKeys contains "kf", then
    1. Set locale.[[CaseFirst]] to r.[[kf]].
  41. If relevantExtensionKeys contains "kn", then
    1. If SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
      1. Set locale.[[Numeric]] to true.
    2. Else,
      1. Set locale.[[Numeric]] to false.
  42. Set locale.[[NumberingSystem]] to r.[[nu]].
  43. Return locale.

1.3 Properties of the Intl.Locale Constructor

The Intl.Locale constructor has the following properties:

1.3.1 Internal slots

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

1.4 Properties of the Intl.Locale Prototype Object

1.4.1 get Intl.Locale.prototype.firstDayOfWeek

Intl.Locale.prototype.firstDayOfWeek 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. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return loc.[[FirstDayOfWeek]].

1.4.2 Intl.Locale.prototype.getCalendars ( )

When the getCalendars method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return CalendarsOfLocale(loc).

1.4.3 Intl.Locale.prototype.getCollations ( )

When the getCollations method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return CollationsOfLocale(loc).

1.4.4 Intl.Locale.prototype.getHourCycles ( )

When the getHourCycles method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return HourCyclesOfLocale(loc).

1.4.5 Intl.Locale.prototype.getNumberingSystems ( )

When the getNumberingSystems method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Return NumberingSystemsOfLocale(loc).

1.4.6 Intl.Locale.prototype.getTimeZones ( )

When the getTimeZones method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let region be GetLocaleRegion(loc.[[Locale]]).
  4. If region is undefined, return undefined.
  5. Return TimeZonesOfLocale(loc).

1.4.7 Intl.Locale.prototype.getTextInfo ( )

When the getTextInfo method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let info be OrdinaryObjectCreate(%Object.prototype%).
  4. Let dir be CharacterDirectionOfLocale(loc).
  5. Perform ! CreateDataPropertyOrThrow(info, "direction", dir).
  6. Return info.

1.4.8 Intl.Locale.prototype.getWeekInfo ( )

When the getWeekInfo method is called, the following steps are taken:

  1. Let loc be the this value.
  2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
  3. Let info be OrdinaryObjectCreate(%Object.prototype%).
  4. Let wi be WeekInfoOfLocale(loc).
  5. Let we be CreateArrayFromList(wi.[[Weekend]]).
  6. Perform ! CreateDataPropertyOrThrow(info, "firstDay", wi.[[FirstDay]]).
  7. Perform ! CreateDataPropertyOrThrow(info, "weekend", we).
  8. Perform ! CreateDataPropertyOrThrow(info, "minimalDays", wi.[[MinimalDays]]).
  9. Return info.

1.5 Properties of Intl.Locale Instances

Intl.Locale instances are ordinary objects that inherit properties from %Intl.Locale.prototype%.

Intl.Locale instances have an [[InitializedLocale]] internal slot.

Intl.Locale instances also have several internal slots that are computed by the constructor:

A Implementation Dependent Behaviour

The following aspects of the ECMAScript 2022 Internationalization API Specification are implementation dependent:

  • In Locale:
    • Support for the Unicode extensions keys "kf", "kn" and the parallel options properties "caseFirst", "numeric" (1.2.1)
    • The set of preferred calendars (1.1.2), collations (1.1.3), hour cycles (1.1.4), numbering systems (1.1.5), and time zones (1.1.6) per locale
    • The default general ordering of characters (characterOrder) within a line per locale (1.1.7)
    • The 'first' day of a week, the minimal days required in the first week of a month or year, and which days of the week are considered as part of the 'weekend', for calendar purposes, per locale (1.1.10)

B Copyright & Software License

Copyright Notice

© 2024 Google, 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.