Darryl
Darryl

Reputation: 1541

How to determine currency symbol position for a culture

I am trying to determine whether the currency symbol for a given culture should appear at the beginning or end of the value. I have not been able to find this bit of information in the .Net CultureInfo, so I thought I'd try a hack:

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 );
}

Alas, this method works only sometimes; in the example above, it works for "en-US" but not the rest of the cultures. At first I thought it was because some cultures read text right-to-left, and the "start" would be the right side, but that explanation did not prove out.

Does anyone see the flaw in my code, or preferably, have a better method for determining the currency symbol position?

Upvotes: 10

Views: 8632

Answers (3)

to StackOverflow
to StackOverflow

Reputation: 124696

Alas, this method works only sometimes; in the example above, it works for "en-US" but not the rest of the cultures.

Why do you say that? As far as I can see, it works for all cultures. Adding a bit of tracing, I get the following, which is exactly what I'd expect: symbolAtBeginning is true IFF the currency symbol is on the left for LTR cultures and on the right for RTL cultures.

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

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460098

You can use the CurrencyPositivePattern of the NumberFormat property of the culture to get the information. The major pitfall is that there are cultures which text is written in right-to-left (RTL) order. Then you have to reverse the logic.

I have created this extension method.

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;
    }
}

You can use it in this way:

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 $

Upvotes: 8

keyboardP
keyboardP

Reputation: 69372

You can use the NumberFormatInfo class to determine that information. You can read the CurrencyPositive property for positive values and it will return an int repesenting the position. From MSDN:

0  $n

1  n$

2  $ n

3  n $ 

Upvotes: 15

Related Questions