I can not convert from string into decimal this is the value of lblTotal="110,00€"
I want to convert it to decimal how can I convert it?
decimal number;
if( Decimal.TryParse(((Label)e.Item.FindControl("lblTotal")).Text.ToString(), out number))
{
}
If you can't parse your string, there can be a few possibilities..
First of all, Decimal.TryParse uses NumberStyles.Number style and this does not includes Currency style. Both are composite styles. That's why you need to use another overload that specify currency symbol and decimal separator.
Second, your Decimal.TryParse uses CurrentCulture settings by default. That means, your CurrencySymbol is not € and/or your NumberDecimalSeparator is not ,.
As a best solution, you can Clone your CurrentCulture and set these properties with Currency style like;
var clone = (CultureInfo) CultureInfo.CurrentCulture.Clone();
clone.NumberFormat.CurrencySymbol = "€";
clone.NumberFormat.NumberDecimalSeparator = ",";
decimal number;
if(decimal.TryParse(((Label)e.Item.FindControl("lblTotal")).Text,
NumberStyles.Currency, clone, out number))
{
// You can use number here
}
You should inform the Decimal.TryParse that you have a currency symbol and what is your culture
string test = "110,00€";
if( Decimal.TryParse(test, NumberStyles.Currency, CultureInfo.CurrentCulture, out number))
{
Console.WriteLine(number);
}
I would also recommend to use a more defensive approach to your retrieving of the label to parse.
Label lbl = e.Item.FindControl("lblTotal") as Label;
if(lbl != Null)
{
.....
}
You can use CultureInfo.CreateSpecificCulture with culture code of Countries using Euro as currency.
Table of Language Culture Names, Codes, and ISO Values Method.
for example Greece, Ireland, Italy uses this currency.
Simply
decimal resault = decimal.Parse(((Label)e.Item.FindControl("lblTotal")).Text.ToString()
,NumberStyles.Currency
,CultureInfo.CreateSpecificCulture("it-IT"));
This will convert your string "110,00€" to decimal correctly Since Italy uses euro(€) as currency.
Or you can use another Culture by searching in the provided link.
Related
How do I parse Norwegian currency (kr) to decimal?
I am trying to parse these:
477,60
2.320,00
This code doesn't work, and throws a decimal parse exception even though I have specified Norway as the culture for parsing.
Convert.ToDecimal("2.320,00", System.Globalization.CultureInfo.GetCultureInfo("nb-NO"))
So Norway culture doesn't have define NumberFormat.NumberGroupSeparator, because of that you receive this exception. So you need to define them:
CultureInfo info = CultureInfo.CreateSpecificCulture("nb-NO");
var numberFormat = info.NumberFormat;
numberFormat.NumberGroupSeparator = ".";
numberFormat.CurrencyGroupSeparator = ".";//this if you are using currency
numberFormat.PercentGroupSeparator = ".";//this for percentages
After that try to use decimal.TryParse method:
decimal result = 0;
decimal.TryParse("2.320,00", NumberStyles.AllowDecimalPoint|NumberStyles.AllowThousands, info, out result);
Here Full Example
I have a string that contains a numeric value in some culture (for example, the string is "$ 1000.00" and the culture is "en"). I want to convert this string to a string in the other culture while preserving as much information about the original format as possible.
For example:
"$ 1000.00" in "en" culture => "1 000,00 $" in "ru" culture.
I've tried the most obvious approach:
private static bool TryConvertNumberString(IFormatProvider fromFormat, IFormatProvider toFormat, string number, out string result)
{
double numericResult;
if (!double.TryParse(number, NumberStyles.Any, fromFormat, out numericResult))
{
result = null;
return false;
}
result = numericResult.ToString(toFormat);
return true;
}
But this does not work the way I want it to: double.TryParse "eats" all information about the presence of currency sign, decimal digits, etc. So if I try to use this method like this:
string result;
TryConvertNumberString(new CultureInfo("en"), new CultureInfo("ru"), "$ 1000.00", out result);
Console.WriteLine(result);
I'll get just 1000, not "1 000,00 $".
Is there an easy way to achieve this behavior using .NET?
Double.ToString(IFormatProvider) method uses the general ("G") format specifier be default and that specifier doesn't return CurrencySymbol property of the current NumberFormatInfo object.
You can just use The "C" (or currency) format specifier as a first parameter in your ToString method which is exactly what you are looking for.
result = numericResult.ToString("C", toFormat);
Here a demonstration.
By the way, ru-RU culture has ₽ as a CurrencySymbol, if you want $ in a result, you can Clone this ru-RU culture, set this CurrencySymbol property, and use that cloned culture in your toFormat part.
var clone = (CultureInfo)toFormat.Clone();
clone.NumberFormat.CurrencySymbol = "$";
result = numericResult.ToString("C", clone);
This is my code:
string myValue = "0,203";
decimal.TryParse(myValue, NumberStyles.Any, CultureInfo.CurrentCulture, out myValueAsDecimal;
...
myValueAsDecimal is 0.203 now
Is it possible that myValueAsDecimal has 0,203 after TryParse or the internal representation of decimal is always 0.203 and I need to format GUI output if I need 0,203?
Is it possible that myValueAsDecimal has 0,203 after TryParse
No. It's just a number - it has no concept of a text format. To think about it another way with a simpler type, consider these two lines of code:
int x = 0x100;
int y = 256;
Are those two values the same? Yes, they represent the same number. If you convert the values of x and y to strings, by default they will both end up as "256" - but they could both end up as "100" if you request a hex representation.
It's important to distinguish between the real value of a variable and a textual representation. Very few types (none that I can think of immediately) carry around information about a textual representation with them - so for example, a DateTime can be parsed from a variety of formats, but has no "memory" of an original text format. It's just a date and time, which could then be formatted according to any format.
If you need to maintain the idea of "a decimal number and the culture in which it was originally represented" then you should create your own class or struct for that pairing. It's not present in decimal itself.
decimal d = 0.203m;
Console.WriteLine(d.ToString(CultureInfo.InstalledUICulture));
Console.WriteLine(d.ToString(CultureInfo.InvariantCulture)); // decimal point: dot
Console.WriteLine(d.ToString(CultureInfo.GetCultureInfo("en-US"))); // default decimal point: dot
Console.WriteLine(d.ToString(CultureInfo.GetCultureInfo("ru-RU"))); // default decimal point: comma
Result:
0,203
0.203
0.203
0,203
Looks like your CurrentCulture has , as a NumberDecimalSeparator and that's why your parsing succeed.
Actually, 0.203 and 0,203 are the same as value. Only matter is their textual representation when you print it.
If you wanna get your value as a 0,203 representation, you can use a culture that has , as a NumberDecimalSeparator.
For example, my culture (tr-TR) has a ,. When you represent your decimal with it, you will get 0,203.
string myValue = "0,203";
decimal myValueAsDecimal;
decimal.TryParse(myValue, NumberStyles.Any, CultureInfo.CurrentCulture, out myValueAsDecimal);
myValueAsDecimal.ToString(new CultureInfo("tr-TR")).Dump(); // 0,203
The value of the Decimal is the same regardless of the Culture, it's
0.203
what changes is its String representation (decimal separator in your case), so
if you want to change decimal separator and don't want to change the Culture
you can just assign NumberDecimalSeparator in your custom NumberFormatInfo e.g.
Decimal d = 0.203M;
NumberFormatInfo myNumberInfo = new NumberFormatInfo() {
NumberDecimalSeparator = "," // Comma, please
};
String result = d.ToString(myNumberInfo); // "0,203"
Situation - The thread culture in my web app has been set to 'es' (Spanish)
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("es");
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("es");
The string value is "0.1"
For the following expression,
var value = "0.1"
provider = CultureInfo.CreateSpecificCulture("en-US")
double.TryParse(value.ToString(), NumberStyles.Any, provider, out number)
number returns 1.0. Which makes me think that it is picking the culture info from the thread. Not the one I provide.
The following unit test passes (as expected).
var numberInEnUS = "0.1";
var spanishCulture = CultureInfo.CreateSpecificCulture("es");
culture = new CultureInfo("en-US", false);
Thread.CurrentThread.CurrentCulture = spanishCulture;
Thread.CurrentThread.CurrentUICulture = spanishCulture;
double number;
double.TryParse(numberInEnUs, NumberStyles.Any, culture, out number);
Assert.AreEqual(0.1, number);
So, the question is why does double.TryParse fail in my application? Theoretically, 0.1 for Spanish is 1 (Separator for spanish is a decimal point '.'). However, number 1000.0 does not get converted to 10000. So, it seems that it fails only for 0.1
Any explanation is highly appreciated!
You say "0.1" is number in spanish. Actually not, It is numberInEnglish or something else
var numberInSpanish = "0.1";//this is number in english culture
It should be
var numberInSpanish = "0,1";//<--Note 0,1
NumberDecimalSeparator for spanish is ,. Parse 0,1 you'll get expected result.
var numberInSpanish = "0,1";
var spanishCulture = CultureInfo.CreateSpecificCulture("es");
var culture = new CultureInfo("en-US", false);
Thread.CurrentThread.CurrentCulture = spanishCulture;
Thread.CurrentThread.CurrentUICulture = spanishCulture;
double number;
double.TryParse(numberInSpanish, NumberStyles.Any, spanishCulture, out number);
Here number is correctly parsed to "0.1"
Your problem is in the mixture of decimal and thousand separators, namely:
'.' - thousand separator in "es" culture, when parsing, will be ignored (e.g. 1.000,0 == 1000,0)
',' - decimal deparator in "es" culture, separates integer and fractional parts
You can easily convince yourself:
var spanishCulture = CultureInfo.CreateSpecificCulture("es");
Char dS = spanishCulture.NumberFormat.NumberDecimalSeparator; // <- ','
Char tS = spanishCulture.NumberFormat.NumberGroupSeparator; // <- '.'
So, in your case the string "0.1" will be converted into 1.0 double since '.' as
being a thousand separator in es culture will be ignored.
You can do either:
Use Invariant culture instead of "es" one:
double.TryParse(numberInNeutral, NumberStyles.Any, CultureInfo.InvariantCulture, out number);
Or use actual Spanish number representation:
var numberInSpanish = "0,1";
double.TryParse(numberInSpanish, NumberStyles.Any, culture, out number);
I finally was able to identify what was wrong. The issue was not with the TryParse() function but the ToString() function.
The value was actually a Double type, not a string as I mentioned above. (My bad, I thought it was not relevant). I was actually doing a value.ToString(). This is where it uses the thread culture and changes the value.
So, if the value was 0.1, the value.ToString() changes it to "0,1". It automatically changes the decimal character based on the Thread culture. The TryParse then uses the en-US culture and convert "0,1" to 1.
To fix it, use Convert.ToString instead and pass in the culture info.
At the end, it was just a silly mistake.
LessonLearnt - Be careful when using ToString() in globalized applications!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert string value to decimal with thousand seperator?
This might be a very simple question.
I want a Convert number to Currency Format.
Double number = 1000000.00;
Convert to
String Strnumber = 10,00,000.00;
Any Idea?..................
But it shows only number not a currency Name
Use the Cformat specifier for currency.
Double number = 1000000.00;
String output = number.ToString("C2");
The Currency ("C") Format Specifier
Demo
Edit: If you don't want a currency-symbol as commented you can use the overload of ToString with the FormatProvider. Then pass a custom NumberFormatInfo without symbol:
var culture = CultureInfo.CurrentCulture;
var mutableNfi = (NumberFormatInfo) culture.NumberFormat.Clone();
mutableNfi.CurrencySymbol = "";
String output = number.ToString("C2", mutableNfi);
decimal value = 16325.62m;
string specifier;
specifier = "N";
Console.WriteLine("{0}: {1}", specifier, value.ToString(specifier));
// Displays: N: 16,325.62
From the required output it seems like you are using the indian number grouping system.
The following should provide you with the value formated in Lakh/Crore etc.
Double number = 1000000.00;
Console.WriteLine(String.Format(new System.Globalization.CultureInfo("en-IN"), "{0:C2}", number));
It should output
10,00,000.00
If you want to display the number without the currency symbol. You can either reformat the number using N general number specifier. The only issue to consider is how you would like the negative numbers displayed. eg,
Double number = 1000000.00;
Console.WriteLine(String.Format(new System.Globalization.CultureInfo("en-IN"), "{0:N2}", number));
Or you can replace the currency symbol within the Number Format specifier. eg,
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-IN");
ci.NumberFormat.CurrencySymbol = "";
Console.WriteLine(String.Format(ci, "{0:N2}", number));
Both should output
10,00,000.00