Intl Locale Info API
Draft Spec
https://tc39.github.io/proposal-intl-locale-info
Stage
Stage 3
- Advanced to Stage 1 in TC39 2020-09 meeting.
- Advanced to Stage 2 in TC39 2021-01-25~28 meeting.
- Jan 2021 TC39 meeting approve to move to Stage 2 WITH the condition to drop unitInfo
- 2021-04-08 ECMA402 meeting, we agreed to propose to TC39 for Stage 3.
- Advanced to advance to Stage 3 in TC39 2021-04 meeting.
- Update during Stage 3 in TC39 2021-07 meeting.
Entrance Criteria for Stage 1 (Proposal)
- Identified “champion” who will advance the addition: Frank Yung-Fong Tang
- Prose outlining the problem or need and the general shape of a solution: See this document
- Illustrative examples of usage: See this document
- High-level API: See this document
- Discussion of key algorithms, abstractions and semantics
- Identification of potential “cross-cutting” concerns and implementation challenges/complexity
- A publicly available repository for the proposal that captures the above requirements:
Entrance Criteria for Stage 2 (Draft)
- Above
- Initial spec text: DONE
- Acceptance Signifies: The committee expects the feature to be developed and eventually included in the standard
Entrance Criteria for Stage 3 (Candidate)
- Above
- Complete spec text
- Designated reviewers have signed off on the current spec text
- All ECMAScript editors have signed off on the current spec text
- Acceptance Signifies: The solution is complete and no further work is possible without implementation experience, significant usage and external feedback.
Champion
- Frank Tang @FrankYFTang
Designated reviewers
- Shane Carr @sffc
- Zibi Braniecki @zbraniecki
ECMAScript editors
- Richard Gibson @gibson042
Implementation Status
- V8 (UPDATE 2021-5-6:) : Behind a flag (cl/2570218 is landed into the trunk)
- $ out/x64.release/d8 --harmony_intl_locale_info
- Chrome - TBD
- Edge - ???
- FireFox - Tracking Bug
- Safari - ???
Scope
A proposal to expose Locale information, such as week data (first day in a week, weekend start day, weekend end day, minimum day in the first week), and text direction hour cycle used in the locale ,measurement system used in the locale.
- Week Data: (User request: https://github.com/tc39/ecma402/issues/6 )
- Prior Arts:
- weekstart JS Library to get first day of week. getWeekStartByRegion(RegionCode) / getWeekStartByLocale(locale);
- mozIntl.getCalendarInfo( locale )
- "date-fns/is_weekend" an non-i18n weekend javascript library
- 'date-fns/start_of_week' an non-i18n weekend javascript library
- JS code snippet of non-i18n solution on stackoverflow
- ICU4J Calendar.getWeekData() and Calendar.WeekData
- ICU Calendar
- Prior Arts:
Hour CycleDROPPED by Champion- Direction (User request: https://github.com/tc39/ecma402/issues/205 )
Measurement System:Prior Arts:
Motivation / Use Case
Locale Information is necessary for many low level operations.
- Direction in textInfo will be needed for layout, and for localization information (bidi boundaries with placeholders etc.)
- WeekInfo will be needed for calendar widgets and applications to display correct monthly and weekly views.
High Level Design
Add methods to Intl to get object to contains group of information:
Week Data
let he = new Intl.Locale("he")
he.weekInfo
// {firstDay: 7, weekend: [5, 6], minimalDays: 1}
let af = new Intl.Locale("af")
af.weekInfo
// {firstDay: 7, weekend: [6, 7], minimalDays: 1}
enGB = new Intl.Locale("en-GB")
enGB.weekInfo
// {firstDay: 1, weekend: [6, 7], minimalDays: 4}
let msBN = new Intl.Locale("ms-BN")
msBN.weekInfo
// {firstDay: 7, weekend: [5, 7], minimalDays: 1} // Brunei weekend is Friday and Sunday but not Saturday
Monday is 1 and Sunday is 7, as defined by ISO-8861 and followed by Temporal proposal
Text Information
l = new Intl.Locale("ar")
let textInfo = l.textInfo;
// { direction: "rtl" }
l.textInfo.direction
// rtl
Defaults
~/v8/v8$ out/x64.release/d8 --harmony_intl_locale_info
V8 version 9.1.0 (candidate)
d8> ar = new Intl.Locale("ar")
ar
d8> ar.calendars
["gregory", "coptic", "islamic", "islamic-civil", "islamic-tbla"]
d8> ar.collations
["compat", "emoji", "eor"]
d8> ar.hourCycles
["h12"]
d8> ar.numberingSystems
["latn"]
d8> ar.timeZones
undefined
d8> arEG = new Intl.Locale("ar-EG")
ar-EG
d8> arEG.calendars
["gregory", "coptic", "islamic", "islamic-civil", "islamic-tbla"]
d8> arEG.collations
["compat", "emoji", "eor"]
d8> arEG.hourCycles
["h12"]
d8> arEG.numberingSystems
["arab"]
d8> arEG.timeZones
["Africa/Cairo"]
d8> arSA = new Intl.Locale("ar-SA")
ar-SA
d8> arSA.calendars
["islamic-umalqura", "gregory", "islamic", "islamic-rgsa"]
d8> arSA.collations
["compat", "emoji", "eor"]
d8> arSA.hourCycles
["h12"]
d8> arSA.numberingSystems
["arab"]
d8> arSA.timeZones
timeZones: ["Asia/Riyadh"]
d8> ja = new Intl.Locale("ja")
ja
d8> ja.calendars
["gregory", "japanese"]
d8> ja.collations
["unihan", "emoji", "eor"]
d8> ja.hourCycles
["h23"]
d8> ja.numberingSystems
["latn"]
d8> ja.timeZones
undefined
d8> jaJP = new Intl.Locale("ja-JP")
ja-JP
d8> jaJP.calendars
["gregory", "japanese"]
d8> jaJP.collations
["unihan", "emoji", "eor"]
d8> jaJP.hourCycles
["h23"]
d8> jaJP.numberingSystems
["latn"]
d8> jaJP.timeZones
["Asia/Tokyo"]}
d8> enUS = new Intl.Locale("en-US")
en-US
d8> enUS.calendars
["gregory"]
d8> enUS.collations
["emoji", "eor"]
d8> enUS.hourCycles
["h12"]
d8> enUS.numberingSystems
["latn"]
d8> enUS.timeZones
["America/Adak", "America/Anchorage", "America/Boise", "America/Chicago", "America/Denver", "America/Detroit", "America/Indiana/Knox", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indianapolis", "America/Juneau", "America/Kentucky/Monticello", "America/Los_Angeles", "America/Louisville", "America/Menominee", "America/Metlakatla", "America/New_York", "America/Nome", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/Phoenix", "America/Sitka", "America/Yakutat", "Pacific/Honolulu"]
d8> enNZ = new Intl.Locale("en-NZ")
en-NZ
d8> enNZ.calendars
["gregory"]
d8> enNZ.collations
["emoji", "eor"]
d8> enNZ.hourCycles
["h12"]
d8> enNZ.numberingSystems
["latn"]
d8> enNZ.timeZones
["Pacific/Auckland", "Pacific/Chatham"]
d8> zh = new Intl.Locale("zh")
zh
d8> zh.calendars
["gregory", "chinese"]
d8> zh.collations
["pinyin", "big5han", "gb2312han", "stroke", "unihan", "zhuyin", "emoji", "eor"]
d8> zh.hourCycles
["h12"]
d8> zh.numberingSystems
["latn"]
d8> zh.timeZones
undefined
d8> zhTW = new Intl.Locale("zh-TW")
zh-TW
d8> zhTW.calendars
["gregory", "roc", "chinese"]
d8> zhTW.collations
["stroke", "big5han", "gb2312han", "pinyin", "unihan", "zhuyin", "emoji", "eor"]
d8> zhTW.hourCycles
["h12"]
d8> zhTW.numberingSystems
["latn"]
d8> zhTW.timeZones
["Asia/Taipei"]
d8> zhHK = new Intl.Locale("zh-HK")
zh-HK
d8> zhHK.calendars
["gregory", "chinese"]
d8> zhHK.collations
["stroke", "big5han", "gb2312han", "pinyin", "unihan", "zhuyin", "emoji", "eor"]
d8> zhHK.hourCycles
["h12"]
d8> zhHK.numberingSystems
["latn"]
d8> zhHK.timeZones
["Asia/Hong_Kong"]
d8> fa = new Intl.Locale("fa")
fa
d8> fa.calendars
["persian", "gregory", "islamic", "islamic-civil", "islamic-tbla"]
d8> fa.collations
["emoji", "eor"]
d8> fa.hourCycles
["h23"]
d8> fa.numberingSystems
["arabext"]
d8> fa.timeZones
undefined
Unit Information DROPPED FEATURE
l = new Intl.Locale("ar")
let unitInfo = l.unitInfo;
// {measurementSystem: "metric"}
l.unitInfo.measurementSystem
// metric
l = new Intl.Locale("en-GB")
l.unitInfo
// {measurementSystem: "uksystem"}
l = new Intl.Locale("en-GB")
l.unitInfo
// {measurementSystem: "uksystem"}
l = new Intl.Locale("en")
l.unitInfo
// {measurementSystem: "ussystem"}