2013-07-03 2 views
3

Я пытаюсь определить, должен ли символ валюты для данной культуры отображаться в начале или в конце значения. Я не смог найти этот бит информации в .Net CultureInfo, так что я бы попробовал хак:Как определить позицию символа валюты для культуры

var cultures = new[] {"en-US", "ar-SA", "as-IN", "tr-TR"}; 
foreach (var culture in cultures) { 
    var cultureInfo = CultureInfo.CreateSpecificCulture(culture); 

    var currencyValue = 1.234.ToString("C", cultureInfo); 

    var rtl = cultureInfo.TextInfo.IsRightToLeft; 

    var symbolAtBeginning = currencyValue.StartsWith(cultureInfo.NumberFormat.CurrencySymbol, false, cultureInfo); 
} 

Увы, этот метод работает только иногда; в приведенном выше примере он работает для «en-US», но не для остальных культур. Сначала я подумал, что это потому, что некоторые культуры читают текст справа налево, а «начало» будет правой стороной, но это объяснение не подтвердилось.

Кто-нибудь видит недостаток в моем коде, или предпочтительно, имеет лучший способ определения позиции символа валюты?

+0

Пред-евро, символ валюты для португальского escudo ($) был помещен вместо десятичной точки (123 $ 45 означает 123.45 ESC). Не уверены, имеют ли какие-либо текущие валюты эту характеристику. В этом случае, я думаю, NumberFormatInfo.CurrencySymbol будет пустой строкой, поэтому ее нельзя использовать для определения ее позиции, а NumberFormatInfo.CurrencyDecimalSeparator будет «$». – Joe

ответ

7

Для определения этой информации вы можете использовать класс NumberFormatInfo. Вы можете прочитать свойство CurrencyPositive для положительных значений, и он вернет int, представляя позицию. От MSDN:

0 $n 

1 n$ 

2 $ n 

3 n $ 
+0

Этот метод работает для as-IN, но не для ar-SA ... – Darryl

5

Вы можете использовать CurrencyPositivePattern в NumberFormat собственности культуры, чтобы получить информацию. Основная ошибка заключается в том, что существуют культуры, текст которых написан в порядке справа налево (RTL). Тогда вам придется отменить логику.

Я создал этот метод расширения.

public static class CultureInfoExtensions 
{ 
    public static bool StartsWithCurrencySymbol(this CultureInfo culture) 
    { 
     bool startsWithCurrencySymbol = 
      culture.NumberFormat.CurrencyPositivePattern == 0 || 
      culture.NumberFormat.CurrencyPositivePattern == 2; 
     return culture.TextInfo.IsRightToLeft ? !startsWithCurrencySymbol : startsWithCurrencySymbol; 
    } 
} 

Вы можете использовать его таким образом:

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) 
    .Where(c => !c.IsNeutralCulture); 
foreach (var ci in cultures) 
{ 
    var currencyValue = 1.234.ToString("C", ci); 
    if (ci.StartsWithCurrencySymbol()) 
     Console.WriteLine("Culture: {0} RTLF? {1} Format: {2}", 
      ci, ci.TextInfo.IsRightToLeft, currencyValue); 
} 

Demo

MSDN:

Value Associated pattern 
0    $n 
1    n$ 
2    $ n 
3    n $ 
+0

Я боюсь, что этот метод не работает для ar-SA в моем примере и в вашем демонстрационном выпуске (http: // ideone. com/yldaJ1), некоторые другие культуры тоже не работают ... – Darryl

+0

@ Darryl: Должен признаться, что я не понимаю следующую ссылку 100%, однако Microsoft сообщает, что в «ar-EG» (так же, как «ar -SA ") _" символ валюты появляется в левой части номера "_, даже если мой код сообщает что-то другое (и даже мс выход). Возможно, вы понимаете, как это понимать: http://www.microsoft.com/middleeast/msdn/arabicsupp.aspx (поиск для «Форматирование числовых данных для определенной арабской культуры») –

+0

Тим, спасибо за помощь.Эта ссылка, кажется, показывает пример, а затем противоречит ей и говорит, что она работает некорректно, и вы должны использовать обходное решение (настройка CultureInfo.NumberFormat.CurrencyPositivePattern). Я нашел поддержку утверждения о том, что арабские символы валюты идут с левой стороны здесь: http://tinyurl.com/pwxpmhn. Однако, если оба они правы, это означает, что Excel ошибочен, как если бы вы форматировали ячейку в качестве валюты и указывали ar-SA, она помещает символ валюты справа. Полностью запутался. – Darryl

0

Увы, этот метод работает только иногда; в приведенном выше примере он работает для «en-US», но не для остальных культур.

Почему вы так говорите? Насколько я вижу, он работает для всех культур. Добавляя немного трассировки, я получаю следующее, что именно то, что я ожидаю: symbolAtBeginning - это истинный IFF, символ валюты находится слева для культур LTR и справа для культур RTL.

culture:en-US currencyValue:$1.23 rtl:False symbolAtBeginning:True 
culture:ar-SA currencyValue:ر.س.‏ 1.23 rtl:True symbolAtBeginning:True 
culture:as-IN currencyValue:₹ 1.23 rtl:False symbolAtBeginning:True 
culture:tr-TR currencyValue:1,23 ₺ rtl:False symbolAtBeginning:False 
+0

В моем тестировании валютная валюта as-IN равна «1.23 ₹», которая терпит неудачу. Кроме того, tr-TR имеет символAtBeginning: True, который также терпит неудачу. – Darryl

+0

Мой тест был на Windows 8, какую ОС вы используете? – Joe

+0

Windows 7, .Net Framework 4.5. – Darryl

Смежные вопросы