Here’s a globalization problem that was put to me recently: how to display a foreign currency in your local format ?
For example if I have a value 123,456.78 and my application is using the en-GB (English (United Kingdom)) culture then this value will display as "£123,456.78". This is correct if the value itself refers to UK Pounds but it is completely incorrect if it refers to US Dollars. If the value refers to US Dollars you could simply display the value using the "English (United States)" culture:-
123456.78.ToString("C", new CultureInfo("en-US"))
This displays "$123,456.78". The double.ToString method accepts an IFormatProvider parameter and extracts the NumberFormatInfo from the CultureInfo object that we pass.
This works in this example but only because the number and currency formatting rules for en-US are the same as for en-GB. If you use a culture with different formatting rules to that of your users then the resulting string will be confusing. For example the correct display of the same value using Hungarian Forints in Hungary is "123 546,78 Ft" but this will give rise to confusion for a reader who uses English (United Kingdom) or English (United States) formatting. What is needed is a way of displaying a foreign currency in a format that the local user will understand.
One solution is the simple DisplayCurrency class below. The static GetNumberFormatInfo method returns a NumberFormatInfo object that is a combination of the currency’s NumberFormatInfo object and the CurrentCulture’s NumberFormatInfo object.
public class DisplayCurrency
public static NumberFormatInfo GetNumberFormatInfo(CultureInfo currencyCultureInfo)
return GetNumberFormatInfo(currencyCultureInfo, CultureInfo.CurrentCulture);
public static NumberFormatInfo GetNumberFormatInfo(CultureInfo currencyCultureInfo, CultureInfo displayCultureInfo)
NumberFormatInfo combinedNfi = (NumberFormatInfo)displayCultureInfo.NumberFormat.Clone();
NumberFormatInfo currencyNfi = currencyCultureInfo.NumberFormat;
if (currencyNfi.NumberDecimalDigits > combinedNfi.NumberDecimalDigits)
// increase the decimals to accomodate the target’s decimals
combinedNfi.NumberDecimalDigits = currencyNfi.NumberDecimalDigits;
combinedNfi.CurrencySymbol = currencyNfi.CurrencySymbol;
The combination is minimalistic in that the new NumberFormatInfo object merely borrows the CurrencySymbol from the currency’s NumberFormatInfo object. In addition it checks the currency’s NumberDecimalDigits and increases the new NumberDecimalDigits if it is lower. This is to ensure that a currency that normally contains decimals does not have its decimals incorrectly truncated. So for example displaying "€123,456.78" when the user’s culture is "ja-JP" (Japanese (Japan)) should not truncate to "€123,456" simply because the Japanese Yen does not have decimals.
Here are the results for a few example cultures:-
hu-HU,Hungarian (Hungary), Hungarian Forint, -123 456,78 Ft, -Ft123,456.78
it-CH,Italian (Switzerland), Swiss Franc, SFr.-123’456.78, -SFr.123,456.78
ms-BN,Malay (Brunei Darussalam), Brunei Dollar, ($123.457), -$123,456.78
fr-CA,French (Canada), Canadian Dollar, (123 456,78 $), -$123,456.78
The solution is not without its problems, however. Like many globalization solutions it makes assumptions about the consumer of the information. In this case it assumes that the user is unfamiliar with the original currency. In the case of the Estonian Kroon, the Malaysian Ringgit and the Guatemalan Quetzal this may well be true. In these examples the solution helpfully displays the currency using formatting that the user is familiar with.<