naishx
naishx

Reputation: 343

How to get specific culture currency pattern

How do i get the currency pattern for a specific culture?

For Example:

Instead of using:

string.Format("{0:c}", 345.10)

I want to use this:

string.Format("#.##0,00 €;-#.##0,00 €", 345.10);

But how do i get the pattern string (like "#.##0,00 €;-#.##0,00 €") for each culture my application needs?

I cant use the "{0:c}" pattern because if the user switches the language the currency should be the same.

Upvotes: 29

Views: 47220

Answers (7)

Mahendra Thorat
Mahendra Thorat

Reputation: 141

For Positive and negative number one can use below code snippet for culture

class Program
{
    static void Main(string[] args)
    {
        List<string> cultures = new List<string> { "ca-ES", "co-FR", "cs-CZ", "cy-GB", "da-DK", "de-AT", "de-CH", "de-DE", "de-LI", "de-LU", "dsb-DE", "en-US", "en-GB" };

        var amount = -16.34M;

        foreach (var c in cultures)
        {
            var cultureInfo = CultureInfo.GetCultureInfo(c);

            var numberFormat = cultureInfo.NumberFormat;
            String formattedAmount = null;
            if (amount >= Decimal.Zero)
            {
                String pattern = null;
                switch (numberFormat.CurrencyPositivePattern)
                {
                    case 0:
                        pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 1:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
                        break;
                    case 2:
                        pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 3:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
                        break;
                }
                formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount);

            }
            else if (amount < Decimal.Zero)
            {
                String pattern = null;
                switch (numberFormat.CurrencyNegativePattern)
                {
                    case 0:
                        pattern = "({0}{1:N" + numberFormat.CurrencyDecimalDigits + "})";
                        break;
                    case 1:
                        pattern = numberFormat.NegativeSign + "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 2:
                        pattern = "{0}" + numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 3:
                        pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign;
                        break;
                    case 4:
                        pattern = "({1:N" + numberFormat.CurrencyDecimalDigits + "}{0})";
                        break;
                    case 5:
                        pattern = numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
                        break;
                    case 6:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign + "{0}";
                        break;
                    case 7:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}" + numberFormat.NegativeSign;
                        break;
                    case 8:
                        pattern = numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
                        break;
                    case 9:
                        pattern = numberFormat.NegativeSign + "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 10:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}" + numberFormat.NegativeSign;
                        break;
                    case 11:
                        pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign;
                        break;
                    case 12:
                        pattern = "{0}" + " " + numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}";
                        break;
                    case 13:
                        pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign + " " + "{0}";
                        break;
                    case 14:
                        pattern = "({0} {1:N" + numberFormat.CurrencyDecimalDigits + "})";
                        break;
                    case 15:
                        pattern = "({1:N" + numberFormat.CurrencyDecimalDigits + "} {0})";
                        break;
                }
                formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount * -1);
            }

            Console.WriteLine(formattedAmount);
        }

        Console.ReadKey();

    }
}

Upvotes: 0

Jamie Thomas
Jamie Thomas

Reputation: 1523

Quick and dirty approach that works for all number formats is:

var culture = CultureInfo.GetCultureInfo("el-GR");
var numberFormat = (NumberFormatInfo)culture.NumberFormat.Clone();
numberFormat.CurrencySymbol = "€";  // Force the currency symbol regardless of culture
var specifier = "C";                // Or any other format specifier
var positivePattern = 1110.ToString(specifier, numberFormat).Replace('1', '#');
var negativePattern = (-1110).ToString(specifier, numberFormat).Replace('1', '#');
var pattern = positivePattern + ";" + negativePattern;

In this case, pattern equals "#.##0,00 €;-#.##0,00 €". This avoids a lot of headaches trying to figure out all of the permutations. I appreciate the question being asked, as it helped and forced me to find an easier answer.

Upvotes: 4

Martin Liversage
Martin Liversage

Reputation: 106906

A CultureInfo contains a NumberFormatInfo and this class describes (among other things) how to format currency for that particular culture.

In particular you can use CurrencyPositivePattern and CurrencyNegativePattern to determine if the currency symbol is placed before or after the amount and of course CurrencySymbol to get the correct currency symbol. All this information is used by .NET when the C format specifier is used.

You can read more about the NumberFormatInfo class on MSDN.

The code below demonstrates some of the steps required to format currency properly. It only uses CurrencySymbol, CurrencyPositivePattern and CurrencyDecimalDigits and thus is incomplete:

var amount = 123.45M;
var cultureInfo = CultureInfo.GetCultureInfo("da-DK");

var numberFormat = cultureInfo.NumberFormat;
String formattedAmount = null;
if (amount >= Decimal.Zero) {
  String pattern = null;
  switch (numberFormat.CurrencyPositivePattern) {
    case 0:
      pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
      break;
    case 1:
      pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
      break;
    case 2:
      pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
      break;
    case 3:
      pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
      break;
  }
  formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount);
}
else {
  // ...
}

Console.WriteLine(formattedAmount);

Of course you could simply use:

var amount = 123.45M;
var cultureInfo = CultureInfo.GetCultureInfo("da-DK");
var formattedAmount = String.Format(cultureInfo, "{0:C}", amount);
Console.WriteLine(formattedAmount);

Upvotes: 34

porges
porges

Reputation: 30580

I think what you're asking is how to change the currency symbol but keep the culture-specific formatting. You can do this by getting a copy of the current NumberFormatInfo and modifying the CurrencySymbol property:

Thread.CurrentThread.CurrentCulture = new CultureInfo("de");
// pretend we are german

var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
nfi.CurrencySymbol = "$$$";
Console.WriteLine(string.Format(nfi,"{0:c}",345.10));

This will output:

345,10 $$$

Without changing the CurrentCulture it outputs (for me):

$$$345.10

Upvotes: 18

Jaapjan
Jaapjan

Reputation: 3385

You need to format your currency/double using:

money.ToString("C", culture);

The hard part is actually getting the right culture based on the ISO code. I do not know how you keep track of the culture you need. Keep in mind this is simply the formatting of your money, not conversion to different currencies/cultures!

More detail:

ISOCurrencySymbol is a part of RegionInfo, which you can create based on CultureInfo, which you can retrieve from your current thread's culture settings. You should create a singleton which implements a dictionary to convert from ISOCurrencyCode to CultureInfo.

Upvotes: 4

Ioannis Karadimas
Ioannis Karadimas

Reputation: 7906

The test below illustrates how you can achieve this:

    [Test]
    public void DisplayEurosInGreeceAndEngland()
    {
        var val = 125.22m;
        Thread.CurrentThread.CurrentCulture
            = Thread.CurrentThread.CurrentUICulture
              = new CultureInfo("el-GR");

        Console.WriteLine(string.Format("{0:n} €", val));

        Thread.CurrentThread.CurrentCulture
            = Thread.CurrentThread.CurrentUICulture
              = new CultureInfo("en-GB");

        Console.WriteLine(string.Format("{0:n} €", val));
    }

By using the standard decimal notation from the currently selected culture, you can display any given value skipping the currency, which you can treat separately.

Upvotes: 1

detaylor
detaylor

Reputation: 7280

Have you tried using string.Format("{0:N2} €", 345.10)? This should format to 2 decimal places in the users culture followed by a space and the euro symbol.

Upvotes: 2

Related Questions