Parse value with Currency symbol

前端 未结 5 1915
耶瑟儿~
耶瑟儿~ 2021-01-21 13:58

I have looked to multiple SO questions on parsing currency, the best (recommended) way seems to be the one I\'m trying below:

var payout = decimal.Parse(\"$2.10\         


        
相关标签:
5条回答
  • 2021-01-21 14:17

    You can try like this:

    decimal currencyValue;
    string inputCurrency = "$12.6";
    if (decimal.TryParse(inputCurrency, NumberStyles.Currency, CultureInfo.CreateSpecificCulture("en-US"), out currencyValue))
      {
          // proceed with currencyValue
      }
    else 
      {
          //Show error ; Conversion failed
      }
    

    For dealing with all currencies you can use the following:

            Dictionary<char, string> currencyCulture = new Dictionary<char, string>();
            currencyCulture.Add('$', "en-US");
            currencyCulture.Add('€', "en-IE");
            // populate all posible values here
            decimal currencyValue;
            string inputCurrency = "€2,66";
            char currencySymbol= inputCurrency.ToCharArray()[0];
            CultureInfo currentCulture= CultureInfo.CreateSpecificCulture(currencyCulture[currencySymbol]);
            if (decimal.TryParse(inputCurrency, NumberStyles.Currency, currentCulture, out currencyValue))
            {
                // proceed with currencyValue
            }
            else 
            {
             //Show error ; Conversion failed
            }
    

    You can choose culture Names from here

    0 讨论(0)
  • 2021-01-21 14:18

    I've expounded on Hari Prasad's answer. With this you can minimize the culture result. Update "SupportedCultures" with the ones you might use in your app.

        private static readonly List<string> SupportedCultures = new List<string> {"en-US", "en-GB", "fr-FR"};
    
        public static void Main()
        {
            var (amount, culture) = ParseCurrencyWithSymbol("$256.12");
            Console.WriteLine($"{culture?.Name} | {amount}");
    
            var (amount2, culture2) = ParseCurrencyWithSymbol("£389.17");
            Console.WriteLine($"{culture2?.Name} | {amount2}");
    
            var (amount3, culture3) = ParseCurrencyWithSymbol("€421,10");
            Console.WriteLine(culture3 != null ? $"{culture3.Name} | {amount3}" : "Failed!");
        }
    
        public static Tuple<decimal?, CultureInfo> ParseCurrencyWithSymbol(string input)
        {
            var culture = CultureInfo.GetCultures(CultureTypes.AllCultures)
                .Where(x => SupportedCultures.Contains(x.Name))
                .FirstOrDefault(c => input.Contains(c.NumberFormat.CurrencySymbol));
    
            if (culture == null) return new Tuple<decimal?, CultureInfo>(null, null);
    
            return new Tuple<decimal?, CultureInfo>(decimal.Parse(input,
                NumberStyles.Currency | NumberStyles.AllowCurrencySymbol |
                NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, culture), culture);
        }
    
    0 讨论(0)
  • 2021-01-21 14:25

    Similar approach @un-lucky mentioned as one of the answer, I tried making it generic and work for every Symbol/Format

    public static decimal ParseCurrencyWithSymbol(string input)
    {
        var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures)
            .GroupBy(c=> c.NumberFormat.CurrencySymbol)
            .ToDictionary(c=> c.Key, c=>c.First());
    
    
        var culture = cultures.FirstOrDefault(c=>input.Contains(c.Key));
    
        decimal result = 0;
        if(!culture.Equals(default(KeyValuePair<string,CultureInfo>)))
        {
            result = decimal.Parse(input, NumberStyles.Currency | NumberStyles.AllowDecimalPoint, culture.Value);
        }
        else
        {
            if( !decimal.TryParse(input, out result))
            {
                throw new Exception("Invalid number format");
            }
        }
    
        return result;
    }
    

    Usage

    decimal output = ParseCurrencyWithSymbol("$2.10");
    

    Working Code

    0 讨论(0)
  • 2021-01-21 14:31

    How about a CleanCurrency method?

    /// Loops each char in the string and returns only numbers, . or ,
    static double? CleanCurrency(string currencyStringIn) {
      string temp = "";
      int n;
      for (int i = 0; i < currencyStringIn.Length; i++) {
        string c = currencyStringIn.Substring(i, 1);
        if (int.TryParse(c, out n) || c == "." || c == ",") {
          temp += c;
        }
      }
      if (temp == "") {
        return null;
      else {
        return double.Parse("0" + temp);
      }
    }
    

    The idea here being to just get an actual number regardless of what the string content is.

    double? payout = CleanCurrency("$3.50");
    
    0 讨论(0)
  • 2021-01-21 14:35

    Pertinent to your particular case, you may use the following code snippet:

    var payout = decimal.Parse("$2.10".Replace("$",""));
    

    If you don't know what the currency symbol would be, then try the following solution:

    string _money = "$2.10";
    var payout = decimal.Parse(_money.Substring(1));
    

    Dealing with commas and decimal points is much more difficult: if this is the issue, refer to the solution given by member @un-lucky.

    Hope this may help.

    0 讨论(0)
提交回复
热议问题