Format decimal in respecting the user’s Locale

I’d like to format a decimal number in an <apex:outputText> respecting the user’s locale:

Using

{0,number,####.###}

should show a German user

10,234

and an American user

10.234

The Java MessageFormat which is used in Salesforce seems to do this but it does not work in Salesforce.

Answer

Yes it is odd that the format strings are not interpreted in a locale sensitive way, i can only assume its due to the Java thread not being set to the users locale internally. There are two ways to approach this problem. Both approaches could be used directly in a controller with custom bindings or wrapped for reuse in a Visualforce Component, as per this idea, How to call parametrized function from Visualforce?.

Dynamically Generating your Format String

Ideally UserInfo would give us the decimal and thousand separators but it does not currently. However we can determine them indirectly. The Apex Decimal.format method is locale sensitive, the following code can be used to derive the separators needed.

public String getDynamicFormatString()
{
    Decimal value = 1000.10;
    String formattedValue = value.format();
    String thousandSep = formattedValue.substring(1,2);
    String decimalSep = formattedValue.substring(5,6);
    return '{0,number,#'+thousandSep+'###'+thousandSep+'###'+thousandSep+'###'+thousandSep+'###'+thousandSep+'##0'+decimalSep+'00}';
}

You can then expose this as binding in your page or component to use with the

<apex:outputText value="{!DynamicFormatString}">
    <apex:param value="{!ValueToFormat}" />
</apex:outputText>

Using outputField component with a dummy SObject Field

With this approach you have to use the outputField component instead of the outputText component. This requires a custom field binding though. So in this case you will have to create a custom object in your org / package who’s sole purpose is to be used for formatting values, no data or user interaction.

For example if you are setting up your view state, construct the object and set its field/s with the values you wish to format, then bind to those fields, the following code fragments show the general idea.

public OutputHelper__c outputHelper {get;set;}

outputHelper = new OutputHelper__c(Number__c = valueToFormat);    

<apex:outputField value="{!outputHelper.Number__c}"/>

The above sample can be scaled to support multiple fields to format by either wrapping it a Visualforce Component or adding more fields e.g. Number1__c. For a lighter version you can hijack a standard field, for example the AnnualRevenue field on the Account.

public Account outputHelper {get;set;}

outputHelper = new Account(AnnualRevenue = valueToFormat);    

<apex:outputField value="{!outputHelper.AnnualRevenue}"/>

Attribution
Source : Link , Question Author : Mathias Maciossek , Answer Author : Community

Leave a Comment