I'm wondering if there's simple way to check if a string is in a value format of any kind. Meaning the number one-thousand could be represented in any of the following ways:
1000
1000.00
1,000
1,000.00
$1,000.00
I've tried double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out n) but that isn't working for items with the currency symbol out in front. So I tried double.TryParse(value NumberStyles.Any | NumberStyles.AllowCurrencySymbol, CultureInfo.InvariantCulture, out n) but that is also not working.
Basically I'd like to check if a value can be considered a number value at all.
The invariant culture does not use $ as its currency symbol; it uses ¤.
Picking the correct culture for parsing is tricky. Obviously, it is best to use the same culture that was used to format the value to begin with. If you know which culture was used, you’re lucky :).
By default, unless a specific culture is specified, CurrentCulture will be used. The current culture can be overridden and set on a per-thread basis, but it defaults to the locale settings of the host operating system. In the absence of other information, CurrentCulture is a reasonable first guess.
I would suggest you || together at least two TryParse calls: one for CurrentCulture (or your best guess as to the culture of origin), and a fallback using InvariantCulture. Include AllowCurrencySymbol on both.
You can use regular expressions
https://regexone.com/references/csharp
you can use below code to accept your cases
1000
1000.00
1,000
1,000.00
$1,000.00
string pattern = #"^\$?(\d{1,3}(\,\d{3})*(\.0{2})?)|(\d+(\.0{2})?)$";
Match result = Regex.Match("$100,000.00", pattern);
if (result.Success)
// your input is in format
Related
I am currently fixing FxCop issues so I encountered issue where I have to provide cultureinfo when converting a string using ToString() .
Currently in my code nothing we are passing as IFormatProvider so I have read some msdn articles saying that when you don't pass any value for cultureinfo it will assign a default value and when you specify CultureInfo as InvariantCulture it will be independent of any culture.
My question is, "Are default and CultureInfo.InvariantCulture one and the same? Can I replace all my code from default to InvariantCulture?"
Ex :
int st = 123;
String s = st.ToString(123); // this will be taken as default
String s = st.ToString(123, CultureInfo.InvariantCulture); // culture is specified externally
Are the second and third lines equivalent?
Is default and CultureInfo.InvariantCulture are one and the same?
No, absolutely not. The default culture depends (initially) on the operating system settings. The invariant culture is meant to be a "neutral" culture.
Your example of 123 isn't a great one, because most (all?) cultures will represent integers the same way - at least until you get into formats with grouping separators etc. (I don't think .NET supports non-Arabic numerals when formatting integers.)
Compare that with formatting a decimal value, for example:
decimal x = 123.45m;
Console.WriteLine(x.ToString()); // Might be 123,45
Console.WriteLine(x.ToString(CultureInfo.InvariantCulture)); // Always 123.45
If you run the above code in (say) France, the default culture will be French, which uses a comma as a decimal separator - so it will print out "123,45".
The rule of thumb to remember is that the invariant culture is suitable for machine-to-machine communications (e.g. formatting values in JSON or XML) whereas other cultures are more suitable for displaying information directly to users.
Although the default culture is originally based on the operating system settings, it can be changed using Thread.CurrentCulture and Thread.CurrentUICulture; the latter is used for looking up translated resources, whereas the former is used for formatting decisions like the above. You can set these properties on any thread, but typically you'd use Thread.CurrentThread.CurrentCulture = ...
No, they are not the same.
The first will take the regional settings from the computer or the culture settings from the application thread running.
The second one will take the English language, according to MSDN:
The invariant culture is culture-insensitive; it is associated with the English language but not with any country/region.
I need to write decimal value to ms access database, but i have a problem with conversion values to decimal in different cultures. Have a values from file, which separates by commma. I try:
public decimal CSingleCulture (string str)
{
string sep = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
string s = str.Replace(",", sep);
return decimal.Parse(s);
}
if NumberDecimalSeparator = "." then work is good, but if NumberDecimalSeparator = "," problems begin... decimal.Parse(s) always return vlaues separates by dot. In this situation, when inserted into a database error occurs.
The recommended way to deal with this is to store the value as a number rather than a string. Both in the database and in your program. When you do that, your current problem simply never arises.
The only time you deal with numbers in string format is when you display them, or accept user input. In those scenarios you can use the user's culture settings to let them see and use their preferred separator.
Should you ever need to convert between string and number for persistence then you must use culture invariant conversion. This appears to be where you are falling down. I suspect that the file you read has no well-defined format. Make sure that when you read and write the file you use CultureInfo.InvariantCulture. If the file does have a well-defined format that differs from the invariant culture, then use an appropriate specific CultureInfo.
Can't actually understand what is it you're trying to accomplish, and I have to agree with the other answer. But one other thing that's good to know is you can use invariant culture like so:
double.Parse("15.0", CultureInfo.InvariantCulture)
This will always expect dot character to delimit your decimal digits regardless of what is set in current thread's culture.
I know that culture rules for dates/numbers is enough for an entire book, I think I have a simple question though..
Does using InvariantCulture basically mean that you explicitly define what culture the value (date/number/whatever) will be inputted/displayed as? And it overrides any other culture setting (such as the user agent's setting)?
If an app is built for an audience of one and only one culture, would it make sense to use InvariantCulture and define how you want values inputted/displayed each time?
Does using InvariantCulture basically mean that you explicitly define what culture the value (date/number/whatever) will be inputted/displayed as?
No. It's just a culture which is a bit like US English, except for a few things like currency sign. It's usually used to format/consume text which is to be understood or was produced by another computer rather than a human.
If an app is built for an audience of one and only one culture, would it make sense to use InvariantCulture and define how you want values inputted/displayed each time?
No, you would use the relevant CultureInfo for that culture. You could also explicitly define the format for dates etc, but that's an orthogonal concern. It may well be best to use one of the predefined standard formats for that culture, but if none of those meet your needs you can always be explicit.
InvariantCulture is Independent of any culture or any factor.
For example if you're using new CultureInfo("en-US") it will get you US English Culture(Which may not be actual US English Culture because OS gives you option to change these setting in Control Panel) it will return the modified version of Culture of "en-US" if any custom formatting applied to it.
In other words InvariantCulture will always gives you a Culture which can never be changed across Systems.
Let's assume you want to serialize some value(say double) and pass to another application or some other thread which is running in different culture leads to serious problems.
Consider the following code
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr");
double source = 455.62d;
string serialized = source.ToString();//455,62 since `, is the decimal seperator` in "fr"
Thread t = new Thread((x) =>
{
double deserialized = double.Parse(((string)x));
Console.WriteLine(string.Format("Deserialized value is {0}", deserialized));//outputs 45562
});
t.CurrentCulture = new CultureInfo("en-US");
t.Start(serialized);
numbers matters more right? consider this string denotes AccountBalance?
Hope this helps
With specific regard to DateTime, the best advice I can give is to use CultureInfo.InvariantCulture for ParseExact and ToString when you have an exact format in mind. (You can also use it with Parse if you happen to know that your input format matches the invariant culture's formats, but I typically avoid this.)
Don't use the invariant culture when interacting with a user.
Keep in mind that the culture contains several items, including the ordering of day/month/year parts, the date and time part separator characters, the character encoding, and the language-specific names of the days of the week, months of the year, and abbreviations including am/pm.
Some examples of when you should use the invariant culture:
Files on disk, especially text files of a predefined format
External APIs, especially JSON or XML
Unit tests, unless you are specifically testing culture issues
Some examples of when you should use a specific culture such as en-US:
User Interface
Reports
This should be simple but I cannot find the answer anywhere.
On our asp.net MVC site, we show currency values and I need these currency values to Always be in USD regardless of the users culture settings.
If I use string.format("{0:C}",value) then it shows the value in what ever culture the use has set.
This is incorrect for us as $1000.00 is not the same thing as 1000.00 euro
I still need to use the language side of this, meaning if they are in France I want to use the French localization resource, so I don't want to completely disregard their culture settings, but how can I make sure the currency is always shown in USD?
Explicitly pass culture to the Format call:
string.Format(new CultureInfo("en-US"), "{0:C}",value)
If you have to mix it with other languages - save result of formatting currency value and insert into other places as string.
Side note: using "en-US" (or any other hard-coded culture) will lead to potentially mismatched representation of negative values i.e. some cultures use -100, while other (100) for negative amounts.
You would have to specify CurrentCulture to be en-US and leave CurrentUICulture as is.
I usually do this in global.asax.cs in the Application_BeginRequest event
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("en-US", false);
It is possible to specify the culture in web.config file but that has one drawback - it takes into account the customized regional settings of the server (if the administrator changed the currency or date format on the server for the en-US culture, it would get picked up this way) - so you can't ever be sure that the application will behave exactly the same as when you created/tested it.
When I try to convert a string to a numeric value with Parse or TryParse or Convert.ChangeType, I can't manage de thousand separator as it is defined in the system:
if I enter :
var d = double.Parse("1,234", CultureInfo.CurrentUICulture);
it does not return 1234.
If I want to use the group separator, I must type :
var d = double.Parse("1,234", NumberStyles.Number, CultureInfo.CurrentUICulture);
This time, the result is that one expected.
But, I don't want to force the use of the thousand separator, I want use it only if the system specify it in the globalization settings. Is there a way to know if the separator is used (I know that I can read the group separator in CultureInfo.CurrentUICulture.NumberFormat.NumberGroupSeparator)
Cheers
Loic
Having Number (which includes AllowThousands) doesn't demand a comma - it simply allows it. So you could use Number with or without the comma. Or use Any or AllowThousands.
Note that "comma" is swappable with "thousands separator" - i.e. in some of Eurupe it may vary (period etc). If you mean "comma is thousands" then use a fixed culture (such as InvariantCulture).
You could always use the second line you use
var d = double.Parse("1,234", NumberStyles.Number, CultureInfo.CurrentUICulture);
as it will correctly convert 1234 as well as 1,234 and it should cover 1.234 on systems that use '.' as the group separator
You should parse user input using CurrentCulture and not CurrentUICulture.
The property CurrentUICulture refers to the language on which the user interface is displayed and CurrentCulture to the current locale specified in Windows. This way a user working with an application that provides a user interface translated to english (CurrentUICulture) can still view/enter, for example, dates and numbers formatted as the locale that he set in Windows (CurrentCulture).