Skip to content
New issue

Have a question about this project?Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of serviceand privacy statement.We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use platformIntlAPIs in Angular's i18n subsystem #54470

Open
JeanMecheopened this issue Feb 15, 2024 · 9 comments · May be fixed by#55283
Open

Use platformIntlAPIs in Angular's i18n subsystem #54470

JeanMecheopened this issue Feb 15, 2024 · 9 comments · May be fixed by#55283
Assignees
Milestone

Comments

@JeanMeche
Copy link
Member

JeanMeche commented Feb 15, 2024

In 2017 (#18284), it was chosen to drop theIntlAPI in favor of custom i18N data extracted from the CLDR (@angular/common/locales/....

Since then theIntlAPI has matured a lot and is now able to cover the feature provided by the framework.

Replacing the legacy i18n implementation with theIntlAPI is move to shift the localisation responsability from the framework to the platform (browsers, Node or Cloud workers).

Benefits of switching to anIntlimplementation

Replacing the legacy implementation with data from locale files with the anIntlbased implementation has several benefits.

  • No need to import locale files to add support for additional languages (default was only english)
  • Bundle size improvements
  • Support for extended locales which allow specifying numbering system, calendar extension etc (iefa-AF-u-nu-latnspecifies Persian, Afghanistan,Western Digits).
  • Support for IANA timezones when formating dates

Deprecations

This will lead to the deprecation of the following locale getters:

  • getCurrencySymbol(code: string, format: 'wide' | 'narrow', locale?: string)
  • getLocaleCurrencyCode(locale: string)
  • getLocaleCurrencyName(locale: string)
  • getLocaleCurrencySymbol(locale: string)
  • getLocaleDateFormat(locale: string, width: FormatWidth)
  • getLocaleDateTimeFormat(locale: string, width: FormatWidth)
  • getLocaleDayNames(locale: string, formStyle: FormStyle, width: TranslationWidth)
  • getLocaleDayPeriods(locale: string, formStyle: FormStyle, width: TranslationWidth)
  • getLocaleDirection(locale: string)
  • getLocaleEraNames(locale: string, width: TranslationWidth)
  • getLocaleExtraDayPeriodRules(locale: string): (Time | [Time, Time])
  • getLocaleExtraDayPeriods(locale: string, formStyle: FormStyle, width: TranslationWidth)
  • getLocaleFirstDayOfWeek(locale: string)
  • getLocaleId(locale: string)
  • getLocaleMonthNames(locale: string, formStyle: FormStyle, width: TranslationWidth)
  • getLocaleNumberFormat(locale: string, type: NumberFormatStyle)
  • getLocaleNumberSymbol(locale: string, symbol: NumberSymbol)
  • getLocalePluralCase: (locale: string) => (value: number)
  • getLocaleTimeFormat(locale: string, width: FormatWidth)
  • getLocaleWeekEndRange(locale: string)
  • getNumberOfCurrencyDigits(code: string)

Those functions, barring exceptions mentioned below, should be replacing by using theIntlAPI withIntl.formatNumber,Intl.formatDate,Intl.Plural.

Getters with none/partial replacements:

  • getLocaleWeekEndRange&getLocaleFirstDayOfWeek:Intl.getWeekInfo()not supported by Firefox (122 ATM)
    • Alternatives
      • luxonfalls back to the ISO week definition (starts on monday, 4 days in week for the week year).
      • day.jsProvides locale data foryearStartandweekStartbut not the weekend range
      • date-fnsProvides locale dataweekStartsOn&firstWeekContainsDatebut not the weekend range.
  • getLocaleDirection:Intl.getTextInfo()not supported by Firefox (122 ATM)
  • getLocaleCurrencySymbol/getLocaleCurrencyCode:We recommend developers fully drop this function as currencies shouldn’t be determined from a locale.

Rolout plan

The feature will be enabled by default for new projects and opt-out on existing project when migrated withng update.

Schedule TBD.

Related PRs

Related issues

Components

@JeanMeche JeanMeche self-assigned this Feb 15, 2024
@ngbot ngbot bot added this to theneedsTriagemilestone Feb 15, 2024
@JeanMeche JeanMeche changed the title Use platform apis for Internationalizion & deprecate Angular Locale getters Use platform Intl APIs in Angular's i18n subsystem Feb 16, 2024
@JeanMeche JeanMeche changed the title Use platform Intl APIs in Angular's i18n subsystem Use platformIntlAPIs in Angular's i18n subsystem Feb 16, 2024
@kyubisation
Copy link

I think this is the right direction for all the listed reasons. 👍

Would it still be possible to customize e.g. date formats/logic?
To explain; Switzerland has four national languages ((swiss-)german, (swiss-)french, italian and romansh) and english as a semi-official language. Switzerland however has no official locale specification, so as far as I know the browser locale data and the CLDR data is just a "best effort" for specifying the locale.
We at SBB (national public transport provider) have e.g. a datetime format that does not match the Intl.DateTimeFormat output.
As we have hundreds of Angular apps at SBB, we would be interested in a solution that is easily applied (e.g. a simple hook provided by a library).

Thank you for the consideration.

@massic80
Copy link

@kyubisationas of now, you could useLuxonandAngular Luxon:you can both configure thetimezoneandBCP-47 language code(just like it-CH or rm-CH).

@kyubisation
Copy link

@massic80Thank you for the reference, but we would prefer using the native Date object (or in the future the temporal objects).

@JeanMeche
Copy link
Member Author

@kyubisation
Yes we aim to keep our API surface as is so custom formatting will still be supported.
There will be some minor regressions though as Intl does not support everything (like some standalone formats, defined in the extra locales).
You'll have a good overview by checking#55283and more specificallypackages/common/test/i18n/format_date_spec.tswhich illustrates the differences we'll have between the current API and the Intl based one.

@massic80
Copy link

@massic80Thank you for the reference, but we would prefer using the native Date object (or in the future the temporal objects).

You're welcome, I understand. I proposed it cause it's a "wrapper" for Intl, nothing "new":)

@daiscog
Copy link

daiscog commented May 29, 2024

While I don't object to this move tointl,I do have concerns that the lack of browser support for some locales will mean features that used to "just work" in Angular no longer will.

For example, Chrome currently does not provide support for the Welsh language,among others,when usingIntl,but currently Angular does. A Welsh language date/time picker, for example, will no longer render correctly in Chrome if I replace use of deprecated functions likegetLocaleDayNameswithIntl-based code.

I think as an opinionated framework, Angular should document how best to replace uses of all deprecated functions, including how to check for runtime support for the target locale, and how to handle cases where the locale data is not available (e.g., perhaps by dynamically checking during initialization and conditionally loading a polyfill).

@kyubisation
Copy link

I have had a look at the implementation.
From my understanding, there is no possibility to "patch" the Angular Intl logic.
This was previously possible, although not officially supported but suggestedhere,by patching the CLDR data.

As an example; Theweekdayformatshortfrom the Intl.DateTimeFormat renders three lettersMon,but company policy specifies two lettersMo.

As mentioned, we would love to have a configuration possibility e.g. via DI, which is not possible at the moment, as e.g. the DatePipe directly callsformatDate.
Again, thank you for your consideration in this matter.

@Ketec
Copy link

Ketec commented Jul 22, 2024

getLocaleFirstDayOfWeek
Date-fns does not have a way to get the value without hard-coded locale imports. You would literally have to import every locale manually.

It shouldn't be marked as deprecated when you opt out of the new system.

@JeanMeche
Copy link
Member Author

@KetecAngular has the same limitations, It needs to provide all those values via static imports.

Luxon for example uses a default fallback for the cases where the API isn't supported:

https://github /moment/luxon/blob/cea7b5f7eac87db57e183f48da97210c47af7034/src/impl/locale.js#L513-L521

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants