-
-
Notifications
You must be signed in to change notification settings - Fork 34
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unit and currency formatting should be supported #838
Comments
Good move with currency |
I agree with adding "left behind" options. We should test drive the process described in #634 to do this. Currency (and unit) is tricky. I tend to agree that not permitting the currency code or the unit to be hardcoded in a message is the I18N ideal. The unit/currency needs to be part of the value. The proposal above seems to suggest that it be a "shadow" option--invalid in an expression, but required in the operand's resolved value. This is a new thing. I also suspect there are cases where someone might want There also might be some additional interactions here. For example, generally setting the currency changes the number of fraction digits on a formatter. However, sometimes users want to have control over the fraction digits. For example, they might want to format a currency amount without the fraction parts ( Alternatively... maybe we don't add currency/unit to the number functions but instead provide separate functions that can make better assumptions, e.g.
Hogwash. The code below (requires ICU4J) is a demo. Messages containing "$5" or "$1" or "$12.37" turn out to need pluralized patterns just as much as "5" and "1" and "12.37" do and current implementation can support this. Yes, the "fraction" rules are often in effect, but there is no need to break this. public static void mf838() {
Locale[] localesToTest = new Locale[] {
Locale.US,
Locale.forLanguageTag("pl-PL"),
Locale.JAPAN,
};
Currency[] currenciesToTest = new Currency[] {
Currency.getInstance("USD"),
Currency.getInstance("JPY"),
};
BigDecimal[] amountsToTest = new BigDecimal[] {
new BigDecimal(0.00),
BigDecimal.ONE,
new BigDecimal(4.37),
new BigDecimal(5.00),
new BigDecimal(5.55),
};
for (Locale locale : localesToTest) {
System.out.println(String.format("\nLocale: %1$s", locale.getDisplayName(Locale.US)));
for (Currency currency : currenciesToTest) {
System.out.println(String.format("Currency: %1$s", currency.getDisplayName(Locale.US)));
for (BigDecimal amount : amountsToTest) {
com.ibm.icu.text.NumberFormat nf = com.ibm.icu.text.NumberFormat.getCurrencyInstance(locale);
nf.setCurrency(com.ibm.icu.util.Currency.fromJavaCurrency(currency));
nf.setMaximumFractionDigits(currency.getDefaultFractionDigits());
nf.setMinimumFractionDigits(currency.getDefaultFractionDigits());
PluralFormat pf = new PluralFormat(locale);
pf.setNumberFormat(nf);
pf.applyPattern("=0 {=0} zero {zero} one {one} two {two} few {few} many {many} other {other}");
System.out.print(String.format("%1$s %2$s", nf.format(amount), pf.format(amount)));
nf.setMaximumFractionDigits(0); // "integer" display of a value
pf.setNumberFormat(nf);
System.out.println(String.format("\t%1$s %2$s", nf.format(amount), pf.format(amount)));
}
}
}
} Output (ICU75.1):
|
I'd be fine with
Could you share some example message in some locale that varies based on the plural category of a currency or unit value? I'm perfectly willing to admit to being wrong, but the code example you shared isn't showing that. |
I think that is a much better approach. Also works better with strongly typed languages (or linters) since you can verify that the input parameters are compatible with the function. |
It is admittedly the case that unit formatting (which includes currency formatting) tends to bring along the noun ("dollars", "centimeters", etc.) and the resulting formatted value often absorbs grammatical variation. However, you can have messages like:
|
Ok, that makes sense. Struck out that line from the post above. |
That's one part of the next steps here, yes, but also separately we need to conclude the specific discussion raised by @sffc in particular on whether or not the default functions should allow for options like |
TLDR: I think we should create The I18N best practice is to carry the unit with the number. Unfortunately, few if any programming languages come with built-in types that do this. This means that there are many applications that have worked around it by creating their own type/class/data structure. There are also many applications that have done something halfway, such as managing the currency or unit contextually. Developers working with non- or semi-internationalized applications should be able to do what they need to do. To implement unit formatting (with currency as a special case) in MF, we need to support this diversity, which means that, in spite of I18N best practices, we will almost certainly need to support Many programming environments support some form of currency formatting as part of their built-in number formatting I18N APIs, but in most cases these were written Long Ago. ICU itself has evolved towards incorporating currencies as a special case of unit formatting via APIs such as I suggest the RGI registry because some runtime environments do not provide currency (or unit) formatting out-of-the-box and we should not be a burden on implementation in weakly-resourced environments. We should also, if we do this, amend the We should also consider whether the default functions should consume unit values as numbers, e.g. |
I disagree that we need to avoid doing the right thing. Any implementation that can't directly support passing a currency value (= number & currency-code) can surely provide a little shim in their API to combine two parameters on their side. |
@macchiati I'm not saying that we should avoid doing the right thing. I'm saying we should provide ways for different users to accomplish the right thing. For example, I was talking with a developer whose application has a currency code associated with all of the values in a "report". They might want to write a message like:
If there is no native "currency amount" type, the |
I think the spec should just normatively require support for combined number and currency/unit input types. Each implementation can do that in their own way. When an upgraded type is available, implementations can use it, and if not, a simple tuple or record can be used. |
Waiting to merge #922, which will close this issue. |
During the February meetings, we ended up leaving out the
:number
style
valuescurrency
andunit
, and their related options:currency
,currencyDisplay
,currencySign
,unit
,unitDisplay
.Furthermore, we also include this direction in the spec:
We should work towards supporting currency and unit formatting in MF2; hence this issue. Looking back to the discussions (also #621) on this topic, it would be good to get input on the parameters of an acceptable solution. To that end, I'm adding assignees here who have been vocal on the topic previously; also CC @ryzokuken.
To get us started, I propose that we re-add all the options currently left out of the tech preview, except for
currency
andunit
. This would mean that in order to use currency or unit formatting, the operand of the:number
function would need to include the appropriate currency or unit in addition to its value, and that supporting this would be left to each implementation.For example, in the JS implementation this could work like this:
With this approach, the placeholder that the translator sees would show that it's a formatted currency, but they would not be able to set the currency; that is provided in the operand.
As we do not specify the formatted results, a conformant implementation could choose to not support currency or unit formatting, and to ignore the relevant options.
We may also want to consider enforcingEdit: I was wrong, see discussion below.exact
selection whenstyle
is notdecimal
, as plural or ordinal selection on currency or unit values does not really make sense.The text was updated successfully, but these errors were encountered: