Format decimal as currency based on currency code

佐手、 提交于 2019-12-22 04:45:27

问题


I have a table of charges with the amount, and the currency code (USD, JPY, CAD, EUR etc.), and am looking for the easiest way to properly format the currency. Using my local culture code (USA) and taking my decimal.ToString("c") gets me $0.00 output, but I'd like the correct currency sign and number of decimals based on the code.

Do any libraries exist for this? I can of course write up a switch statement and custom rules for each one, but thought this must have been done before.

Update:

I've modified Jon B's sample code as follows

static IDictionary<string, string> GetCurrencyFormatStrings()
{
    var result = new Dictionary<string, string>();

    foreach (var ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
    {
        try
        {
            var ri = new RegionInfo(ci.Name);
            result[ri.ISOCurrencySymbol] =
                  string.Format("{0}#,#0.{1};({0}#,#0.{1})",
                                ri.CurrencySymbol,
                                new string('0', 
                                i.NumberFormat.CurrencyDecimalDigits));
        }
        catch { }
    }

    return result;
}

This allows me to simply go Amount.ToString(Currency["JPY"]), and the format will output the comma separator in my local context, but put the correct currency symbol and decimal places in automatically.

Let me know if anyone has a cleaner way of doing this, or I will mark Jon's answer as correct shortly.


回答1:


You could build a dictionary to go from ISO currency symbol (USD) to currency symbol ($):

static void Main(string[] args)
{
    var symbols = GetCurrencySymbols();

    Console.WriteLine("{0}{1:0.00}", symbols["USD"], 1.5M);
    Console.WriteLine("{0}{1:0.00}", symbols["JPY"], 1.5M);

    Console.ReadLine();
}

static IDictionary<string, string> GetCurrencySymbols()
{
    var result = new Dictionary<string, string>();

    foreach (var ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
    {
        try
        {
            var ri = new RegionInfo(ci.Name);
            result[ri.ISOCurrencySymbol] = ri.CurrencySymbol;                    
        }
        catch { }
    }

    return result;
}

That's the basic idea, you'll need to tweak that to suit your needs.

Note that you can certainly use the CultureInfo class to convert to a string for a specific culture, but as noted in Alexei's comment, that will cause each string to be a little different (like 1.00 vs 1,00). Whichever you use depends on your needs.




回答2:


public static class DecimalExtension
{
    private static readonly Dictionary<string, CultureInfo> ISOCurrenciesToACultureMap =
        CultureInfo.GetCultures(CultureTypes.SpecificCultures)
            .Select(c => new {c, new RegionInfo(c.LCID).ISOCurrencySymbol})
            .GroupBy(x => x.ISOCurrencySymbol)
            .ToDictionary(g => g.Key, g => g.First().c, StringComparer.OrdinalIgnoreCase);

    public static string FormatCurrency(this decimal amount, string currencyCode)
    {
        CultureInfo culture;
        if (ISOCurrenciesToACultureMap.TryGetValue(currencyCode, out culture))
            return string.Format(culture, "{0:C}", amount);
        return amount.ToString("0.00");
    }
}

Here are the results of calling FormatCurrency for a few different currency codes:

decimal amount = 100;

amount.FormatCurrency("AUD");  //$100.00
amount.FormatCurrency("GBP");  //£100.00
amount.FormatCurrency("EUR");  //100,00 €
amount.FormatCurrency("VND");  //100,00 ?
amount.FormatCurrency("IRN");  //? 100.00



回答3:


Should be done by passing the CultureInfo:

CultureInfo ci = new CultureInfo("en-GB");
amount.ToString("C", ci);


来源:https://stackoverflow.com/questions/13364984/format-decimal-as-currency-based-on-currency-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!