views:

1021

answers:

5

One of the fun parts of multi-cultural programming are numbers formats.

Americans use 10,000.50, Germans use 10.000,50, French use 10 000,50 etc. My first approach would be: Take the string, parse it backwards, until I encounter a separator and use this as my decimal separator. The obvious flaw with that: 10.000 would be interpreted as 10. Another approach: if the string contains 2 different non-numeric characters, use the last one as the decimal separator and discard the others. If I only have one, check if it occurs more than once and discard it if it does. It it only appears once, check if it has 3 digits after it. If yes, discard it, otherwise use it as decimal separator.

The obvious "best solution" would be to detect the User's culture or Browser, but that does not work if you have a Frenchman an an en-US Windows/Browser.

I just wonder: does the .net Framework contain some mythical black magic floating point parser that is better than Double.(Try)Parse() in trying to auto-detect the number format?

+6  A: 

I don't know the ASP.NET side of the problem but .NET has a pretty powerful class: System.Globalization.CultureInfo. You can use the following code to parse a string containing a double value:

double d = double.Parse("100.20", CultureInfo.CurrentCulture);
// -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);

If ASP.NET somehow (i.e. using HTTP Request headers) passes current user's CultureInfo to either CultureInfo.CurrentCulture or CultureInfo.CurrentUICulture, these will work fine.

huseyint
+1  A: 

You can't please everyone. If I enter ten as 10.000, and someone enters ten thousand as 10.000, you cannot handle that without some knowledge of the culture of the input. Detect the culture somehow (browser, system setting - what is the use case? ASP? Internal app, or open to the world?), or provide an example of the expected formatting, and use the most lenient parser you can. Probably something like:

double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);
Chris Marasti-Georg
A: 

Using double.Parse() with a CultureInfo only works if I know what the user is. If I have a french person typing in 10 000,50 on a US-Windows, CurrentCulture is enUS which uses , as a group and . as the decimal separator, so the space will make it nor work.

Michael Stum
+2  A: 

I think the best you can do in this case is to take their input and then show them what you think they meant. If they disagree, show them the format you're expecting and get them to enter it again.

Ryan Fox
+1  A: 

The difference between 12.345 in French and English is a factor of 1000. If you supply an expected range where max < 1000*min, you can easily guess.

Take for example the height of a person (including babies and children) in mm.

By using a range of 200-3000, an input of 1.800 or 1,800 can unambiguously be interpreted as 1 meter and 80 centimeters, whereas an input of 912.300 or 912,300 can unambiguously be interpreted as 91 centimeters and 2.3 millimeters.

Michiel de Mare