tc39 / ecma402

Status, process, and documents for ECMA 402
https://tc39.es/ecma402/
Other
526 stars 102 forks source link

Add unit preferences and "smart" unit resolution #277

Open sffc opened 5 years ago

sffc commented 5 years ago

215 adds the ability to format unit strings. It does not attempt to solve the problem of picking the correct unit to use given a locale, context, and magnitude.

CLDR has some limited data for this: https://unicode.org/cldr/trac/browser/tags/release-33-1-d04/common/supplemental/supplementalData.xml#L4770

I have issues filed to improve this data structure. For example: https://unicode.org/cldr/trac/ticket/11452

Ultimately, what I would like to eventually see is one function that maps from context, locale, and magnitude to unit identifier, and then let #215 map from unit identifier, locale, and number to string.

Additional question: should this new hypothetical API also include unit conversion?

rxaviers commented 5 years ago

One argument against it is the analogous situation for currency. Trying to guess the currency based on locale is considered a bad pattern according to UTS#35: "Note: Currency values should never be interchanged without a known currency code. You never want the number 3.5 interpreted as $3.50 by one user and €3.50 by another. Locale data contains localization information for currencies, not a currency value for a country. A currency amount logically consists of a numeric value, plus an accompanying currency code (or equivalent). The currency code may be implicit in a protocol, such as where USD is implicit. But if the raw numeric value is transmitted without any context, then it has no definitive interpretation."

Following that line of thought, I suggest exposing the preferred units given a locale, context, and magnitude instead. Leave to the user the decision on which to use and any needed conversions.

sffc commented 5 years ago

That quotation sounds like it's about parsing an unknown currency. For measurement units, what I was thinking by "conversion" was basically, ok, I have a road length in meters from my database, and I want to show it to a user in en-GB; convert from meters to the locale's unit and then display.

rxaviers commented 5 years ago

The quotation refers to a bad function formatCurrency(3.5) that would display '$3.50' for one locale and '€3.50' for another.

I brought this analogy considering your suggestion is about a formatUnit(3.5) that would do something similar. If it's about a formatUnit(100, 'meter', {style: "smart"}) that would pick the localized unit and do any necessary conversions, then I think it would be fine.

sffc commented 5 years ago

Ah, I see what you mean now.

An all-in-one API could be as simple as,

new Intl.NumberFormat("en-us", {
    style: "smart-unit",
    unitContext: "length-road",
});

For measurement units, we could declare a standard unit that the number is to be provided in. For the "length" type, I would pick meters, for example. If we want to allow users to change it, though, that would be relatively easy:

new Intl.NumberFormat("en-us", {
    style: "smart-unit",
    unitContext: "length-road",
    inputUnit: "length-mile"
});

I would also like to see a standalone library that lets you get the "smart" unit without formatting to a string. Maybe that could be something for the standard library, https://github.com/tc39/proposal-javascript-standard-library.

littledan commented 5 years ago

I can definitely see the case for this standalone library. What's harder for me to understand is why you'd want this to be integrated into Intl.NumberFormat--it seems like saving a little bit of typing for some broader confusion. Wouldn't you typically need to go and get the unit back out with resolvedOptions(), negating much of the length benefit?

sffc commented 5 years ago

ICU ticket with some ideas:

https://unicode-org.atlassian.net/browse/ICU-20568

younies commented 4 years ago

Here is the proposal for supporting smart unit preferences: https://github.com/tc39/proposal-smart-unit-preferences