Reputation: 2451
Well, for avoiding Format Exceptions
in a Convert.ToDecimal
, ToSingle
, and ToDouble
, I use a Foreach
with an array of CultureInfo
class, but, is there a method for detecting which are the "possible cultures" from a string? (I say possible cultures because some culture shares their format.)
An example: If I use "1,080.47" I want to return en-US
, and if I use "1.080,47" I want to return fr-FR
, es-ES
, etc.
What do you recommend?
Upvotes: 2
Views: 1482
Reputation: 9991
Just to be clear, and I'll quote MSDN
*In the .NET Framework 4 and previous versions, by default, the culture of all threads is set to the Windows system culture*
However, there's a distinction between input and output. I'll start with the trivial part.
Output
This is the easy one. We're in control. If the user wants a ,
as a decimal separator , so shall be done.
decimalValue.ToString(123.456, CultureInfo.GetCultureInfo("nb-NO"))
Output:
123,456
Input
This is the tricky part. I'm a Norwegian (as I guess you've figured out), and yes, we use the comma (,
) as a decimal separator. Does this mean that all my fellows will input ,
instead of .
? No. So applies to dates. Some users input dd-MM-yyyy "instead" of dd.MM.yyyy. Welcome to the UXD. However (and this might not be true for others), I'm yet to see a user trying to input a thousand separator
when working with floating numbers.
Conclusion
My best advice is to use the default Culture Info as the output, and as implied, format the user input if not valid.
Note
FYI, the Culture Info reveals many a useful properties. Here's a few related to my anwwer:
Upvotes: 0
Reputation: 20464
The same numeric formatting can pertains to various cultures, so maybe I'm wrong but I'll imagine that the best you could do is match the valid cultures for an specific format and then use your own logic to decide, something like this which is only an example for Single:
Public Function MatchCultures(ByVal str As String) as list(of string)
Dim ValidCultures As New List(Of String)
Dim CultureNames As IEnumerable(Of String) =
From cultureInfo In cultureInfo.GetCultures(CultureTypes.AllCultures)
Select cultureInfo.Name
For Each CultureName As String In CultureNames
Try
Convert.ToSingle(str, New CultureInfo(CultureName))
ValidCultures.Add(CultureName)
Catch ex As FormatException
' Do nothing
End Try
Next
Return ValidCultures
End Function
Also you could speed-up the procedure if you want to limit the CultureNames to a specific range lets say { "en-Us", "fr", "es", etc... } 'cause the list of culture-names is too big: http://msdn.microsoft.com/es-es/goglobal/bb896001.aspx
Anyways I think that you're approaching the problem into a bad solution, you should use the "TryParse" helper methods from datatypes like:
If Single.TryParse("1.000", New Single) Then...
Upvotes: 2