Форматирование валюты в .NET - PullRequest
3 голосов
/ 19 ноября 2011

Я пытаюсь понять, как работает форматирование валюты в .NET Framework.Насколько я понимаю, Thread.CurrentCulture.NumberFormatInfo.CurrencySymbol содержит символ валюты местной культуры.

Но, на мой взгляд, в реальном мире нет четкой связи 1: 1 между конкретной культурой и символом валюты.Например, я могу находиться в Великобритании, но выставляю счета в евро.Или я могу жить в Исландии и получать счета от американских поставщиков в долларах США.Или я могу жить в Швеции, но мой банковский счет использует евро.Я понимаю, что в некоторых случаях вы можете просто предположить, что используется местная валюта, но часто это не так.

В этих случаях я бы клонировал CultureInfo и установил бы валютусимвол вручную на клоне, а затем использовать клон при форматировании суммы?Даже если символ валюты недействителен, я думаю, что все же имеет смысл использовать другие свойства NumberFormatInfo, например CurrencyDecimalSeparator.

1 Ответ

6 голосов
/ 19 ноября 2011

Абсолютно. Я сделал это, используя технику, основанную на сообщении в блоге Мэтта Вебера . Вот пример, который использует формат вашей культуры для валюты (десятичные разряды и т. Д.), Но использует символ валюты и количество десятичных разрядов, подходящих для данного кода валюты (поэтому один миллион иен в культуре en-US будет отформатирован как ¥1,000,000).

Вы, конечно, можете изменить его, чтобы выбрать, какие свойства текущей культуры и культуры валюты сохраняются.

public static NumberFormatInfo GetCurrencyFormatProviderSymbolDecimals(string currencyCode)
{
    if (String.IsNullOrWhiteSpace(currencyCode))
        return NumberFormatInfo.CurrentInfo;


    var currencyNumberFormat = (from culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)
                                let region = new RegionInfo(culture.LCID)
                                where String.Equals(region.ISOCurrencySymbol, currencyCode,
                                                    StringComparison.InvariantCultureIgnoreCase)
                                select culture.NumberFormat).First();

    //Need to Clone() a shallow copy here, because GetInstance() returns a read-only NumberFormatInfo
    var desiredNumberFormat = (NumberFormatInfo)NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture).Clone();
    desiredNumberFormat.CurrencyDecimalDigits = currencyNumberFormat.CurrencyDecimalDigits;
    desiredNumberFormat.CurrencySymbol = currencyNumberFormat.CurrencySymbol;

    return desiredNumberFormat;
}
...