Safari 15.4 released recently and among many things it includes a few new internationalization features. And while the blog post does explain which ones they are, it doesn't really mention what they do. So, I'll give you a brief summary for all of them.
Intl.Locale
calendars/collations/hourCycles/numberingSystems/timeZones
All of these properties will return an array of the things the locale supports. Here are some examples of what each one will return so that you can get an idea of what they're used for.
// calendars for Japanese (Japan) will return the Gregorian calendar and the Japanese calendar
new Intl.Locale('ja-JP').calendars; // ['gregory', 'japanese']
// collations A.K.A. ordering rules for Spanish (Mexico) will return traditional style ordering, European ordering rules, and emoji
new Intl.Locale('es-MX').collations; // ['trad', 'emoji', 'eor']
// hourCycles for Traditional Chinese (China) will be a 23 hour cycle
new Intl.Locale('zh-Hant-CN').hourCycles; // ['h23']
// but for English (USA) it will be a 12 hour cycle
new Intl.Locale('en-US').hourCycles; // ['h12']
// numberingSystems for Arabic (Bahrain) will return Arabic-Indic digits
new Intl.Locale('ar-BH').numberingSystems; // ['arab']
// but for Portuguese (Brazil) it will return Latin digits
new Intl.Locale('pr-BR').numberingSystems; // ['latn']
// timeZones for English (New Zealand) will return Auckland and Chatham
new Intl.Locale('en-NZ').timeZones; // ['Pacific/Auckland', 'Pacific/Chatham']
Previous versions of the spec supported the non-plural versions of each of these properties. However, they will be undefined unless they are set through the options
parameter of the Locale
constructor.
// not setting with options
new Intl.Locale('ja-JP').calendar; // undefined
new Intl.Locale('ja-JP').calendars; // ['gregory', 'japanese']
// setting with options
new Intl.Locale('ja-JP', {calendar: 'gregory'}).calendar; // 'gregory'
new Intl.Locale('ja-JP', {calendar: 'gregory'}).calendars; // ['gregory'] as the 'japanese' one will get removed due to the options
// you can also set other calendars not there by default on the locale so be careful
new Intl.Locale('ja-JP', {calendar: 'buddhist'}).calendar; // 'buddhist'
new Intl.Locale('ja-JP', {calendar: 'buddhist'}).calendars; // ['buddhist']
textInfo
The textInfo
property currently contains an object with a single direction
property which serves to indicate whether the locale's text is written right-to-left or left-to-right.
// Arabic
new Intl.Locale("ar").textInfo; // { direction: 'rtl'}
// Spanish
new Intl.Locale("es").textInfo; // { direction: 'ltr'}
weekInfo
The weekInfo
currently contains an object with various information regarding how weeks work on that region. It's especially useful when creating calendar UIs.
// week info for the UK
const gb = new Intl.Locale("en-GB").weekInfo;
gb.firstDay; // 1 - week starts on Monday
gb.weekend; // [6, 7] - weekend is Saturday and Sunday
gb.minimalDays; // 4 - for a week to be shown as the first week of a month it needs to be at least 4 days long
// week info for Algeria
const dz = new Intl.Locale("ar-DZ").weekInfo;
dz.firstDay; // 6 - week starts on Saturday
dz.weekend; // [5, 6] - weekend is Friday and Saturday
dz.minimalDays; // 1 - for a week to be shown as the first week of a month it needs to be at least 1 days long
Browser Support
All the above features are supported in the following browsers:
- Safari: 15.4 - supported
- Chrome/Edge: 92* - supported (MDN says only with a flag but it worked in Edge 99 with no flags)
- Firefox: 99 - not supported
Intl.DisplayNames
type: 'calendar'
This type option will allow you to get the localized name for any of the supported calendar types.
new Intl.DisplayNames(['en'], { type: 'calendar' }).of('gregory'); // 'Gregorian Calendar'
new Intl.DisplayNames(['en'], { type: 'calendar' }).of('japanese'); // 'Japanese Calendar'
type: 'dateTimeField'
With this type option you can get localized strings for many different common words related to dates and time. Some examples include:
new Intl.DisplayNames(['en'], { type: 'dateTimeField' }).of('year'); // 'year'
new Intl.DisplayNames(['en'], { type: 'dateTimeField' }).of('minute'); // 'minute'
new Intl.DisplayNames(['en'], { type: 'dateTimeField' }).of('weekday') // 'day of the week'
languageDisplay
option
The languageDisplay
option is an option that can only be used for type: 'language'
that determines the format for the string representing the language. It can be either 'dialect' or 'standard'.
new Intl.DisplayNames(['en'], { type: 'language', languageDisplay: 'dialect' }).of('en-AU'); // Australian English
new Intl.DisplayNames(['en'], { type: 'language', languageDisplay: 'standard' }).of('en-AU'); // English (Australia)
Browser Support
No MDN data for these features specifically, but I tested them in the following browsers:
- Safari: 15.4 - supported
- Chrome/Edge: 99 - supported
- Firefox: 99 developer edition - supported
Intl.DateTimeFormat
New timeZoneName
types
Four new types of timeZoneName
were added: 'shortOffset', 'longOffset', 'shortGeneric', and 'longGeneric'.
const date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738));
new Intl.DateTimeFormat('en', { timeZone: 'JST', timeZoneName: 'shortOffset'}).format(date); // '12/20/2020, GMT+9'
new Intl.DateTimeFormat('en', { timeZone: 'JST', timeZoneName: 'longOffset'}).format(date); // '12/20/2020, GMT+09:00'
new Intl.DateTimeFormat('en', { timeZone: 'JST', timeZoneName: 'shortGeneric'}).format(date); // '12/20/2020, Japan Time'
new Intl.DateTimeFormat('en', { timeZone: 'JST', timeZoneName: 'longGeneric'}).format(date); // '12/20/2020, Japan Standard Time'
Browser Support
- Safari: 15.4 - supported
- Chrome/Edge: 99* - supported (MDN doesn't list this as supported but it worked in my tests. It might work in earlier versions. MDN issue)
- Firefox: 91 - supported
Intl.NumberFormat / Intl.PluralRules
Safari 15.4's release notes mention that it added support for formatRange()
and formatRangeToParts()
in NumberFormat
and for selectRange()
in PluralRules
. However, as the time of writing, those functions don't seem to be actually implemented in Safari 15.4 (Mac OS 10.15) nor have they been implemented in other browsers.
new Intl.NumberFormat('de-DE').formatRange; // undefined
new Intl.NumberFormat('de-DE').formatRangeToParts; // undefined
new Intl.PluralRules('de-DE').selectRange; // undefined
Conclusion
Hopefully this article helped you understand better what all these new features were about and whether you can actually begin using them.
Credits
Cover photo by Nareeta Martin on Unsplash.
Top comments (1)
what to do with old versions of Safari? Currently these throw an error when using the "shortOffset" timeZoneName…