3

Suppose I have the following <f:convertNumber> to format a currency-type number:

<f:convertNumber type="currency" locale="#{userSession.locale}" pattern="$###,###.###" />

In English, a million would be 1,000,000 but in Germany, it should be 1.000.000. My question is: If I use the above pattern, will JSF be aware of the number format of the specified locale and automatically use the correct separator?

If not, I'd be very grateful if you could show me how I can format a currency number and at the same time specify the right number separator.

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • Check it by changing `locale-config` in faces-config. – vels4j Nov 04 '13 at 09:51
  • I think that you can remove the `pattern="$###,###.###"` and it will work as is, read more: http://stackoverflow.com/questions/11835888/fconvertnumber-remove-comma-as-thousand-separator and http://stackoverflow.com/questions/7856152/set-decimal-separator-when-formatting-hintputtext – Daniel Nov 04 '13 at 10:11
  • @Daniel: I need to use a customised pattern because Java always put the currency symbol as a prefix. For Chinese, I need the currency symbol to be suffix as `pattern="###,###.### 元"` – Mr.J4mes Nov 04 '13 at 11:30

1 Answers1

5

It's important to know and understand that the <f:convertNumber> tag uses DecimalFormat under the covers. You can find all pattern characters in its javadoc.

It seems that you expected that the DecimalFormat pattern characters , and . are also actually used in the final format. This is untrue. It are really merely pattern characters (like as d, M, y, etc as used bySimpleDateFormat). Basically, the pattern character , tells DecimalFormat to print the "grouping separator" as specified by the given locale and, equivalently, the pattern character . tells DecimalFormat to print the "decimal separator" as specified by the given locale.

In effects, the actual character being printed depends on the given locale. For English locale (locale="en"), the "grouping separator" being printed is just coincidentally also ,, but for German locale (locale="de") the "grouping separator" being printed is indeed ..


Unrelated to the concrete problem, the type attribute of <f:convertNumber> has totally no effect if the pattern attribute is specified. The type attribtue is basically superfluous in this example and can safely be removed without any side effects.

If you remove the pattern attribute, then it'll actually be used and you'll see that the default pattern for a currency is being used, which is same as ¤#,##0.00 for English locale and ¤ #,##0.00 for German locale. Also note that the pattern character representing the currency symbol is not $, but ¤. The currency symbol can be set separately via currencySymbol attribute. So the correct approach for currencies would be:

<f:convertNumber type="currency" locale="#{userSession.locale}" currencySymbol="$" />

Again, see the DecimalFormat javadoc as linked before.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Thank you!!! Great answer as always :). I need to use a customised pattern because Java always put the currency symbol as a prefix. For Chinese, I need suffix to represent money number like `pattern="###,###.### 元"`. The `type="currency"` is more for self-documenting purpose :P. – Mr.J4mes Nov 05 '13 at 01:44
  • I do have another question though. Is there a reason why `` cannot set the `currencySymbol` based on the locale? If I need to set it manually, I suppose it'd require using a `ResourceBundle` to store the symbol for different languages, am I right? – Mr.J4mes Nov 05 '13 at 01:49
  • Because the currency is not necessarily locale specific. More than often prices are shown in a fixed currency (e.g. dollars or euros only). Only the currency format is locale specific. And yes, you can use a resource bundle to hold the actual currency symbols. – BalusC Nov 05 '13 at 08:27
  • @BalusC: How did you arrive at ¤#,##0.00 for English locale and ¤ #,##0.00 for German locale. Where will i see the default pattern if i remove the pattern attribute? – Farhan stands with Palestine Dec 31 '14 at 14:17
  • @Shirgill: just look at the result and apply logical thinking. Or, if you want programmatic evidence, just run `System.out.println(((DecimalFormat)NumberFormat.getCurrencyInstance(Locale.ENGLISH)).toLocalizedPattern());` and another one with `Locale.GERMAN`. – BalusC Dec 31 '14 at 14:21