angular / angular

Deliver web apps with confidence 🚀
https://angular.dev
MIT License
96.09k stars 25.43k forks source link

Use platform `Intl` APIs in Angular's i18n subsystem #54470

Open JeanMeche opened 8 months ago

JeanMeche commented 8 months ago

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

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

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

Benefits of switching to an Intl implementation

Replacing the legacy implementation with data from locale files with the an Intl based implementation has several benefits.

Deprecations

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

Those functions, barring exceptions mentioned below, should be replacing by using the Intl API with Intl.formatNumber, Intl.formatDate, Intl.Plural.

Getters with none/partial replacements :

Rolout plan

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

Schedule TBD.

Related PRs

Related issues

Components

kyubisation commented 5 months ago

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 commented 5 months ago

@kyubisation as of now, you could use Luxon and Angular Luxon: you can both configure the timezone and BCP-47 language code (just like it-CH or rm-CH).

kyubisation commented 5 months ago

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

JeanMeche commented 5 months ago

@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 #55283 and more specifically packages/common/test/i18n/format_date_spec.ts which illustrates the differences we'll have between the current API and the Intl based one.

massic80 commented 5 months ago

@massic80 Thank 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 commented 5 months ago

While I don't object to this move to intl, 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 using Intl, 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 like getLocaleDayNames with Intl-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 commented 4 months ago

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 suggested here, by patching the CLDR data.

As an example; The weekday format short from the Intl.DateTimeFormat renders three letters Mon, but company policy specifies two letters Mo.

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 calls formatDate. Again, thank you for your consideration in this matter.

Ketec commented 3 months ago

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 commented 3 months ago

@Ketec Angular 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.com/moment/luxon/blob/cea7b5f7eac87db57e183f48da97210c47af7034/src/impl/locale.js#L513-L521