views:

399

answers:

2

Hi,

I want to format my numbers throughout the application in a consistent way, no matter what culture is chosen. In fact, it's "non-standard" even for the basic culture that we're using.

I want to format "{1500.50:c}" as: '1500.50', but the standard for my culture 'nl-NL', is: '€ 1.500,00'. We don't have the user-rights, since it's a webapplication, to register custom cultures, therefore we're looking for a runtime solution.

We want a "set and forget" solution. Not a Util class with static (extension) methods, but an application wide solution, so we can continue to use the standard .ToString("c"), or ToString("N") logic, which would follow our custom rules. This would be to alter the .NumberFormat of the Culture, but how? Everything seems to be readonly.

Thanks.

+1  A: 

I would create a base class on which all your pages are derived and set the parameters you want for the culture there like so:

public class PageBase : Page
{
    protected override void InitializeCulture()
    {
        var culture = CultureInfo.CreateSpecificCulture( CultureInfo.CurrentCulture.Name );
        culture.NumberFormat.CurrencySymbol = string.Empty;
        culture.NumberFormat.NumberDecimalDigits = 2;
        culture.NumberFormat.NumberDecimalSeparator = ".";
        culture.NumberFormat.NumberGroupSeparator = ",";
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        base.InitializeCulture();
    }
}

Or you could build your culture off an existing one:

public class PageBase : Page
{
    protected override void InitializeCulture()
    {
        var culture = CultureInfo.CreateSpecificCulture( "en-US" );
        culture.NumberFormat.CurrencySymbol = string.Empty;
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;

        base.InitializeCulture();
    }
}
Thomas
.CreateSpecificCulture was my missing link, I couldn't get a writeable culture. I've placed it in the Global.axas (HttpApplication) .Begin_Request event. Now every request gets assigned my culture.
Gabriël
A: 

If you really want to format your numbers in a consistent way no matter what culture is chosen, you should either use a specific format pattern ("#.##") along with the InvariantCulture (if the invariant culture doesn't have the values you want for number format properties, you can create your own "Invariant" culture for this purpose. Setting the thread's current culture can have other unintended consequences as this culture will be used by default for all formatting and parsing some of which may be outside your control.

By the way, you don't have to use CreateSpecificCulture; you can just create a CultureInfo directly:

        CultureInfo currentWithOverriddenNumber = new CultureInfo(CultureInfo.CurrentCulture.Name);
        currentWithOverriddenNumber.NumberFormat.CurrencyPositivePattern = 0; // make sure there is no space between symbol and number
        currentWithOverriddenNumber.NumberFormat.CurrencySymbol = ""; // no currency symbol
        currentWithOverriddenNumber.NumberFormat.CurrencyDecimalSeparator = "."; //decimal separator
        currentWithOverriddenNumber.NumberFormat.CurrencyGroupSizes = new int[] { 0 }; //no digit groupings
        currentWithOverriddenNumber.NumberFormat.NumberGroupSizes = new int[] { 0 };
        currentWithOverriddenNumber.NumberFormat.NumberDecimalSeparator = "."; //decimal separator

        Thread.CurrentThread.CurrentCulture = currentWithOverriddenNumber;
Eric MSFT
The point is we need to support 2 different styles which are disconnect from the culture we're using, but should be applied througout the whole application. Formatting using the pattern of invariantculture aren't optimal solutions.Thanks for the input.
Gabriël