Reputation: 1315
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.
Upvotes: 0
Views: 5039
Reputation: 16
I came across something similar when migrating some "legacy" .NET sites and services from one web server to another.
I ended up writing an IIS module to enable overriding the hosts currency, number and date/time formats (dictated by the regional settings of the host server) without editing code. Initially, it did not support a global override (apply specific format regardless of culture) but this seemed like a great enhancement so has been added.
It enables customization of currency symbols, decimal separators, number group separators, long date format, short date format... basically all the properties that can be explicitly set via the NumberFormatInfo and DateTimeFormatInfo objects in .NET. All done via the web.config file (ie: no code changes required).
Hoping this might save somebody some time and/or frustration.
Upvotes: 0
Reputation: 3276
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;
Upvotes: 0
Reputation: 64635
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();
}
}
Upvotes: 2