Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse String to Decimal using any decimal seperator

Tags:

c#

I want to parse a string from an Text input to decimal. The value represents a currency value.

Currently i got this solution:

private Decimal CastToDecimal(string value) 
{
    Decimal result;
    var valid = Decimal.TryParse(value, NumberStyles.Currency, null, out result);
    return valid ? result : -1;
}

This works pretty well so far, except for possible culture-differences. I'm german and i expect most users to enter german-style puctuation. But it is possible that someone uses "." instead of "," and the conversion will fail.

"123,45€" => 123.45

"123.456,78€" => 123456.78

"123.45€" => 12345 <- I want the result to be 123.45 here

Is there a way to automatically detect the used culture for a decimal value? Such that it does not matter if you use german or english punctuation, you still get the same result?

Update:

Thanks to your help, i created a method which does what i want (i think).

private static Decimal CastToDecimal(string value)
{
    Decimal resultDe;
    Decimal resultEn;
    var style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
    var cultureDe = CultureInfo.CreateSpecificCulture("de-DE");
    var cultureEn = CultureInfo.CreateSpecificCulture("en-GB");
    var deValid = Decimal.TryParse(value, style, cultureDe, out resultDe);
    var enValid = Decimal.TryParse(value, style, cultureEn, out resultEn);
    var minVal = Math.Min(resultDe, resultEn);
    var maxVal = Math.Max(resultDe, resultEn);
    if (!deValid)
        return resultEn;
    if (!enValid)
        return resultDe;
    return BitConverter.GetBytes(decimal.GetBits(minVal)[3])[2] > 2 ? maxVal : minVal;
}

This code...

    Console.WriteLine(CastToDecimal("123,45"));
    Console.WriteLine(CastToDecimal("123.45"));
    Console.WriteLine(CastToDecimal("123,450"));
    Console.WriteLine(CastToDecimal("123.450"));
    Console.WriteLine(CastToDecimal("123.123,45"));
    Console.WriteLine(CastToDecimal("123,123.45"));

returns this:

123,45
123,45
123450
123450
123123,45
123123,45
like image 606
Alexander Mills Avatar asked Oct 28 '25 15:10

Alexander Mills


1 Answers

the solution at http://msdn.microsoft.com/en-us/library/3s27fasw%28v=vs.110%29.aspx which includes setting the NumberStyle may be helpful.

...
value = "1.345,978";
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands;
culture = CultureInfo.CreateSpecificCulture("es-ES");
if (Double.TryParse(value, style, culture, out number))
   Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
   Console.WriteLine("Unable to convert '{0}'.", value);
// Displays:  
//       Converted '1.345,978' to 1345.978. 

value = "1 345,978";
if (Double.TryParse(value, style, culture, out number))
   Console.WriteLine("Converted '{0}' to {1}.", value, number);
else
   Console.WriteLine("Unable to convert '{0}'.", value);
...
like image 93
shelbypereira Avatar answered Oct 31 '25 04:10

shelbypereira