Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make TryParse compatible with comma or dot decimal separator

The problem: Let's assume you are using a dot "." as a decimal separator in your regional setting and have coded a string with a comma.

string str = "2,5";

What happens when you decimal.TryParse(str, out somevariable); it?

somevariable will assume 0.

What can you do to solve it?

1- You can

decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out somevariable);

And it will return 25, and not 2.5 which is wrong.

2- You can

decimal.TryParse(str.Replace(",","."), out num);

And it will return the proper value, BUT, if the user uses "," as a decimal separator it will not work.

Possible solution that I can't make it work:

Get the user decimal separator in regional settings:

char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);

And make somehow the replace from ",",sepdec , that way it would stay a comma if its a comma, and replace by an actual dot if the user uses dots.

Hints?

Edit: Many users posted useful information, lately, using the arguments NumberStyles.Any, CultureInfo.GetCultureInfo("pt-PT") on a tryParse wouldn't work if your separator is set to "," So it pretty much doesnt fullfill the premise of making a tryparse "universal".

I'll work around this, if anyone has more hints you'r welcome

like image 482
ng80092b Avatar asked Apr 04 '15 22:04

ng80092b


People also ask

How to use decimal TryParse in c#?

TryParse(ReadOnlySpan<Char>, NumberStyles, IFormatProvider, Decimal) Converts the span representation of a number to its Decimal equivalent using the specified style and culture-specific format. A return value indicates whether the conversion succeeded or failed.

What is used as a separator for decimal numbers?

The decimal separator is also called the radix character. Likewise, while the U.K. and U.S. use a comma to separate groups of thousands, many other countries use a period instead, and some countries separate thousands groups with a thin space.


1 Answers

I know the thread is a little bit older, but I try to provide an answer.

I use regular expression to determine the used number format in the string. The regex also matches numbers without decimal separators ("12345").

var numberString = "1,234.56"; // en
// var numberString = "1.234,56"; // de
var cultureInfo = CultureInfo.InvariantCulture;
// if the first regex matches, the number string is in us culture
if (Regex.IsMatch(numberString, @"^(:?[\d,]+\.)*\d+$"))
{
    cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in de culture
else if (Regex.IsMatch(numberString, @"^(:?[\d.]+,)*\d+$"))
{
    cultureInfo = new CultureInfo("de-DE");
}
NumberStyles styles = NumberStyles.Number;
bool isDouble = double.TryParse(numberString, styles, cultureInfo, out number);

HTH

Thomas

like image 102
ace lafit Avatar answered Oct 08 '22 02:10

ace lafit