Hi I want to find if there is any better way to parse the string to Decimal which covers various format
$1.30
£1.50
€2,50
2,50 €
2.500,00 €
I see a lot of examples using culture to convert . & ,. But in my case, I don't have anything to identify the culture.
This display field I get from the client and I need to extract the value.
I tried following (which didn't work for all scenario) but would like to know if we have any best way to handle this.
Decimal.Parse(value,NumberStyles.Currency |
NumberStyles.Number|NumberStyles.AllowThousands |
NumberStyles.AllowTrailingSign | NumberStyles.AllowCurrencySymbol)
I also tried to use Regex to remove the currency sign but unable to convert both 1.8 or 1,8 in one logic.
Well, assuming you always get a valid currency format, and it's only the culture that changes, you could guess which character is used as a decimal point and which is used as a thousands separator by checking which appears the last in the number. Then remove all the thousand separators and parse it like its culture was invariant.
The code would look like the following:
// Replace with your input
var numberString = "2.500,00 €";
// Regex to extract the number part from the string (supports thousands and decimal separators)
// Simple replace of all non numeric and non ',' '.' characters with nothing might suffice as well
// Depends on the input you receive
var regex = new Regex"^[^\\d-]*(-?(?:\\d|(?<=\\d)\\.(?=\\d{3}))+(?:,\\d+)?|-?(?:\\d|(?<=\\d),(?=\\d{3}))+(?:\\.\\d+)?)[^\\d]*$");
char decimalChar;
char thousandsChar;
// Get the numeric part from the string
var numberPart = regex.Match(numberString).Groups[1].Value;
// Try to guess which character is used for decimals and which is used for thousands
if (numberPart.LastIndexOf(',') > numberPart.LastIndexOf('.'))
{
decimalChar = ',';
thousandsChar = '.';
}
else
{
decimalChar = '.';
thousandsChar = ',';
}
// Remove thousands separators as they are not needed for parsing
numberPart = numberPart.Replace(thousandsChar.ToString(), string.Empty);
// Replace decimal separator with the one from InvariantCulture
// This makes sure the decimal parses successfully using InvariantCulture
numberPart = numberPart.Replace(decimalChar.ToString(),
CultureInfo.InvariantCulture.NumberFormat.CurrencyDecimalSeparator);
// Voilá
var result = decimal.Parse(numberPart, NumberStyles.AllowDecimalPoint | NumberStyles.Number, CultureInfo.InvariantCulture);
It does look a bit of complicated for a simple decimal parsing, but I think should do the work for all the input numbers you get or at least the most of them.
If you do this in some sort of loop, you might want to use compiled regex.
The problem here is that in one case . means decimal point but in other it is a thousnads separator. And then you have , as decimal separator. Clearly, it is impossible for the parser to "guess" what is meant, so the only thing you can do is to decide on some rules on how to handle which case.
If you have control over the UI the best approach would be to validate user input and just reject any value that can't be parsed with an explanation on which format is expected.
If you have no control over the UI, the second best option would be to check for some "rules" and then devise which culture is appropriate for that given input and try to run it through decimal.TryParse for that given culture.
For the given input you have, you could have the following rules:
input.StartsWith("$") -> en-US
input.StartsWith("£") -> en-GB
input.StartsWith("€") || input.EndsWith("€") -> de-DE
These could reasonably handle all cases.
In code:
static void Main(string[] args)
{
string[] inputs =
{
"$1.30",
"£1.50",
"€2,50",
"2,50 €",
"2.500,00 €"
};
for (int i = 0; i < inputs.Length; i++)
{
Console.Write((i + 1).ToString() + ". ");
if (decimal.TryParse(inputs[i], NumberStyles.Currency,
GetAppropriateCulture(inputs[i]), out var parsed))
{
Console.WriteLine(parsed);
}
else
{
Console.WriteLine("Can't parse");
}
}
}
private static CultureInfo GetAppropriateCulture(string input)
{
if (input.StartsWith("$"))
return CultureInfo.CreateSpecificCulture("en-US");
if (input.StartsWith("£"))
return CultureInfo.CreateSpecificCulture("en-GB");
if (input.StartsWith("€") || input.EndsWith("€"))
return CultureInfo.CreateSpecificCulture("de-DE");
return CultureInfo.InvariantCulture;
}
Output:
1.30
1.50
2.50
2.50
2500.00
The only way you could do that is just strip string from symbols and change . and , to decimal separator. Something like:
public decimal UniversalConvertDecimal(string str)
{
char currentDecimalSeparator = Convert.ToChar(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
str = str.Replace('.', currentDecimalSeparator);
str = str.Replace(',', currentDecimalSeparator);
StringBuilder builder = new StringBuilder(str.Length);
foreach(var ch in str)
{
if(Char.IsDigit(ch) || ch == currentDecimalSeparator)
builder.Add(ch);
}
string s = builder.ToString();
return Convert.ToDecimal(s);
}
First you have to get current decimal separator from your system.
Then you have to replace . and , with current decimal separator.
Next, you will have to strip the string from any other char than a digit or decimal separator. At the end you can be sure that Convert.ToDecimal is going to work. But I don't know if it is something you want to achieve.
If you need some mechanism to save currency to database, there is a far simpler solution. Just convert this currency to least currency part. For example instead of $1, save 100 cents.
So if you have $1.99, just multiply it by 100 and you will get: 199 cents. And this integer can be saved to db.
Related
Hi i need to convert a decimal value based on the culture info.
For EG :
If en-US culture the decimal value will be like 21.56 and in
tr-TR which is turkey culture info , here the same value will be as 21,56
Si my requirement is to whatever the decimal value , but i need to get in en-US as default. I need my decimal value seperated by dot and i dont want the decimal value of comma.
I tried converting using the below code
CultureInfo userCulture = new CultureInfo("tr-TR");
string fromVisioAPI = "35,2083";
string display = double.Parse(fromDb, userCulture).ToString();
and here the output was "35.2083" which was i expected, but here am hardcoding the tr-TR value and i dunno how many culture does the same comma and dot difference.
This was a normal replacement and i need to be a proper culture conversion
So what's the best way of converting comma decimal values to dot decimal values using culture info..?
You need to know the culture info for the data to parse. If that was static, you could simply hard code it or configure it in the app.config.
Otherwise you could use CultureInfo.CurrentCulture.
To convert the values back to string you should use the ToString overload with a specific culture info:
var visioApiCulture =
new CultureInfo(ConfigurationManager.AppSettings["VisioApiCulture"]);
or
var visioApiCulture = CultureInfo.CurrentCulture;
-
string fromVisioApi = "35,2083";
string display = double
.Parse(fromVisioApi, visioApiCulture)
.ToString(CultureInfo.InvariantCulture);
Assuming the Visio API is running on the same computer as your code, then the Windows culture info that Visio is using is very likely the same as what your program is getting as its default. You can get the current culture from the CultureInfo.CurrentCulture property: https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.currentculture(v=vs.110).aspx
It think the below code can help you ..
public double? ConvertStringToDouble(string strDoubleValue)
{
//Checking null
if (strDoubleValue == null)
{
return null;
}
//Making trim
strDoubleValue = strDoubleValue.Trim();
//Checking empty
if (strDoubleValue == string.Empty)
{
return null;
}
//If the amout treat dot(.) as decimal separator
if (strDoubleValue.IndexOf('.')!=-1)
{
//If multiple . is present then the amount is invaid
if (strDoubleValue.Count(o=>o=='.')>1)
{
return null;
}
//removing thousand separators
//it might not be needed
strDoubleValue = strDoubleValue.Replace(",", "");
return ConvertPlainStringToDouble(strDoubleValue);
}
//If the amout treat dot(,) as decimal separator
//then it must not use ',' as thousand separator
if (strDoubleValue.Count(o => o == ',') > 1)
{
//removing thousand separators
//it might not be needed
strDoubleValue = strDoubleValue.Replace(",", "");
return ConvertPlainStringToDouble(strDoubleValue);
}
//Here will be logic that the string contains single comma , is treated here as
//deciaml separator or comma separator
//int charCountBeforeComma = strDoubleValue.IndexOf(',');
//int charCountAfterComma = strDoubleValue.Length - (charCountBeforeComma + 1);
////If charCountAfterComma is not in 3rd position than
////the comma cannot be thousand separator example: 458,5896
//if (charCountAfterComma!=3)
//{
// //removing thousand separators
// //it might not be needed
// strDoubleValue = strDoubleValue.Replace(",", ".");
// return ConvertPlainStringToDouble(strDoubleValue);
//}
//if string having more than 3 char before comma like 4589,548
//it means no thousand separator used else the amount should represent like this 4,589,548
//you can use below code
//if (charCountBeforeComma>3)
//{
// //removing thousand separators
// //it might not be needed
// strDoubleValue = strDoubleValue.Replace(",", "");
// return ConvertPlainStringToDouble(strDoubleValue);
//}
//if all above missed than i am sorry
//it means the string is like 458,458 or 58,458 format
//you need to put some logical condition here
//??????
}
private Double? ConvertPlainStringToDouble(string strPlainDoubleValue)
{
Double amount;
if (Double.TryParse(strPlainDoubleValue, out amount))
{
return amount;
}
return null;
}
I tried to attend all logical condition to resolve the issue .. but in end .. there is something nee
d to fill by you .. :)
You should use the universal format properties in the API - those don't depend on the culture setting.
For example, to get the formula of a cell, use FormulaU - this will keep all the numbers in the . means decimal point, , means thousands separator format.
Using Result should also work, since it's supposed to return a double, not a string - if you're getting a string, either you're using an incorrect interop library, or you're doing something wrong. You can use ResultStrU as a work-around, again, to get an universal format string.
Is there a way to make the C# TryParse() functions a little more... strict ?
Right now, if you pass in a string containing numbers, the correct decimal & thousand separator characters, it often just seems to accept them, even if the format doesn't make sense, eg: 123''345'678
I'm looking for a way to make TryParse not be successful if the number isn't in the right format.
So, I'm based in Zurich, and if I do this:
decimal exampleNumber = 1234567.89m;
Trace.WriteLine(string.Format("Value {0} gets formatted as: \"{1:N}\"", exampleNumber, exampleNumber));
...then, with my regional settings, I get this...
Value 1234567.89 gets formatted as: "1'234'567.89"
So you can see that, for my region, the decimal place character is a full-stop and the thousand-separator is an apostrophe.
Now, let's create a simple function to test whether a string can be parsed into a decimal:
private void ParseTest(string str)
{
decimal val = 0;
if (decimal.TryParse(str, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
Okay, let's call this function with a few strings.
Which of the following strings would you think would get successfully parsed by this function ?
Below are the results I got:
ParseTest("123345.67"); // 1. Parsed "123345.67" as 123345.67
ParseTest("123'345.67"); // 2. Parsed "123'345.67" as 123345.67
ParseTest("123'345'6.78"); // 3. Parsed "123'345'6.78" as 1233456.78
ParseTest("1''23'345'678"); // 4. Parsed "1''23'345'678" as 123345678
ParseTest("'1''23'345'678"); // 5. Couldn't parse: "'1''23'345'678"
ParseTest("123''345'678"); // 6. Parsed "123''345'678" as 123345678
ParseTest("123'4'5'6.7.89"); // 7. Couldn't parse: "123'4'5'6.7.89"
ParseTest("'12'3'45'678"); // 8. Couldn't parse: "'12'3'45'678"
I think you can see my point.
To me, only the first two strings should've parsed successfully. The others should've all failed, as they don't have 3-digits after a thousand separator, or have two apostrophes together.
Even if I change the ParseTest to be a bit more specific, the results are exactly the same. (For example, it happily accepts "123''345'678" as a valid decimal.)
private void ParseTest(string str)
{
decimal val = 0;
var styles = (NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands);
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
So, is there a straightforward way to not allow badly formatted strings to be accepted by TryParse ?
Update
Thanks for all of the suggestions.
Perhaps I should clarify: what I'm looking for is for the first two of these strings to be valid, but the third one to be rejected.
ParseTest("123345.67");
ParseTest("123'456.67");
ParseTest("12'345'6.7");
Surely there must be a way to use "NumberStyles.AllowThousands" so it can optionally allow thousand-separators but make sure the number format does make sense ?
Right now, if I use this:
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
I get these results:
Parsed "123345.67" as 123345.67
Parsed "123'456.67" as 123456.67
Parsed "12'345'6.7" as 123456.7
And if I use this:
if (decimal.TryParse(str, styles, CultureInfo.InvariantCulture, out val))
I get these results:
Parsed "123345.67" as 123345.67
Couldn't parse: "123'456.67"
Couldn't parse: "12'345'6.7"
This is my problem... regardless of CultureInfo settings, that third string should be rejected, and the first two accepted.
The easiest way to tell if it is correctly formatted based on the current culture would be to compare the resulting number after formatting with the original string.
//input = "123,456.56" -- true
//input = "123,4,56.56" -- false
//input = "123456.56" -- true
//input = "123,,456.56" -- false
string input = "123456.56";
decimal value;
if(!decimal.TryParse(input, out value))
{
return false;
}
return (value.ToString("N") == input || value.ToString() == input);
This will succeed for inputs that completely omit thousand separators and inputs that specify correct thousand separators.
If you need it to accept a range of decimal places then you would need to grab the number of characters after the decimal separator and append it to the "N" format string.
Putting together all the useful suggestions here, here's what I ended up using.
It's not perfect, but, for my corporate app, it does at least reject numeric-strings which "don't look right".
Before I present my code, here's the differences between what my TryParseExact function will accept, and what the regular decimal.TryParse would accept:
And here's my code.
I'm sure there's a more efficient way of doing some of this, using regex or something, but this is sufficient for my needs, and I hope it helps other developers:
public static bool TryParseExact(string str, out decimal result)
{
// The regular decimal.TryParse() is a bit rubbish. It'll happily accept strings which don't make sense, such as:
// 123'345'6.78
// 1''23'345'678
// 123''345'678
//
// This function does the same as TryParse(), but checks whether the number "makes sense", ie:
// - has exactly zero or one "decimal point" characters
// - if the string has thousand-separators, then are there exactly three digits inbetween them
//
// Assumptions: if we're using thousand-separators, then there'll be just one "NumberGroupSizes" value.
//
// Returns True if this is a valid number
// False if this isn't a valid number
//
result = 0;
if (str == null || string.IsNullOrWhiteSpace(str))
return false;
// First, let's see if TryParse itself falls over, trying to parse the string.
decimal val = 0;
if (!decimal.TryParse(str, out val))
{
// If the numeric string contains any letters, foreign characters, etc, the function will abort here.
return false;
}
// Note: we'll ONLY return TryParse's result *if* the rest of the validation succeeds.
CultureInfo culture = CultureInfo.CurrentCulture;
int[] expectedDigitLengths = culture.NumberFormat.NumberGroupSizes; // Usually a 1-element array: { 3 }
string decimalPoint = culture.NumberFormat.NumberDecimalSeparator; // Usually full-stop, but perhaps a comma in France.
string thousands = culture.NumberFormat.NumberGroupSeparator; // Usually a comma, but can be apostrophe in European locations.
int numberOfDecimalPoints = CountOccurrences(str, decimalPoint);
if (numberOfDecimalPoints != 0 && numberOfDecimalPoints != 1)
{
// You're only allowed either ONE or ZERO decimal point characters. No more!
return false;
}
int numberOfThousandDelimiters = CountOccurrences(str, thousands);
if (numberOfThousandDelimiters == 0)
{
result = val;
return true;
}
// Okay, so this numeric-string DOES contain 1 or more thousand-seperator characters.
// Let's do some checks on the integer part of this numeric string (eg "12,345,67.890" -> "12,345,67")
if (numberOfDecimalPoints == 1)
{
int inx = str.IndexOf(decimalPoint);
str = str.Substring(0, inx);
}
// Split up our number-string into sections: "12,345,67" -> [ "12", "345", "67" ]
string[] parts = str.Split(new string[] { thousands }, StringSplitOptions.None);
if (parts.Length < 2)
{
// If we're using thousand-separators, then we must have at least two parts (eg "1,234" contains two parts: "1" and "234")
return false;
}
// Note: the first section is allowed to be upto 3-chars long (eg for "12,345,678", the "12" is perfectly valid)
if (parts[0].Length == 0 || parts[0].Length > expectedDigitLengths[0])
{
// This should catch errors like:
// ",234"
// "1234,567"
// "12345678,901"
return false;
}
// ... all subsequent sections MUST be 3-characters in length
foreach (string oneSection in parts.Skip(1))
{
if (oneSection.Length != expectedDigitLengths[0])
return false;
}
result = val;
return true;
}
public static int CountOccurrences(string str, string chr)
{
// How many times does a particular string appear in a string ?
//
int count = str.Length - str.Replace(chr, "").Length;
return count;
}
Btw, I created the table image above in Excel, and noticed that it's actually hard to paste values like this into Excel:
1'234567.89
Does Excel complain above this value, or try to store it as text ? Nope, it also happily accepts this as a valid number, and pastes it as "1234567.89".
Anyway, job done.. thanks to everyone for their help & suggestions.
It's because parsing just skips the NumberFormatInfo.NumberGroupSeparator string and completely ignores the NumberFormatInfo.NumberGroupSizes property. However, you can implement such a validation:
static bool ValidateNumberGroups(string value, CultureInfo culture)
{
string[] parts = value.Split(new string[] { culture.NumberFormat.NumberGroupSeparator }, StringSplitOptions.None);
foreach (string part in parts)
{
int length = part.Length;
if (culture.NumberFormat.NumberGroupSizes.Contains(length) == false)
{
return false;
}
}
return true;
}
It's still not completely perfect, as the MSDN says:
The first element of the array defines the number of elements in the least significant group of digits immediately to the left of the NumberDecimalSeparator. Each subsequent element refers to the next significant group of digits to the left of the previous group. If the last element of the array is not 0, the remaining digits are grouped based on the last element of the array. If the last element is 0, the remaining digits are not grouped.
For example, if the array contains { 3, 4, 5 }, the digits are grouped similar to "55,55555,55555,55555,4444,333.00". If the array contains { 3, 4, 0 }, the digits are grouped similar to "55555555555555555,4444,333.00".
But you can see the point now.
I'm a bit stuck: I am trying to perform an if statement comparing a label.text that originally has a currency string created from .ToString("C");
and a decimal. I have tried converting the label to decimal since I'm going to be comparing it to a decimal but it keeps triggering an exception:
Input string was not in a correct format.
here is my current code:
if(Convert.ToDecimal(SomeLabel.Text) > 1000.00m) { //DO SOMETHING }
//SomeLabel.Text has a value of $1000.00
//SomeLabel.Text has a value of $1000.00
The dollar sign is the reason for the issue. Yoa are probably using a different currency symbol. You can force it with decimal.Parse/decimal.TryParse(which handles invalid input):
string input = "$1000.00";
decimal decimalValue;
if(decimal.TryParse(input, out decimalValue))
{
// using current CurrencySymbol, same as Convert.ToDecimal
Console.WriteLine("Converted successfully: " + decimalValue);
}
else
{
var usCulture = new CultureInfo("en-US");
if (decimal.TryParse(input, NumberStyles.Currency, usCulture, out decimalValue))
{
// using dollar sign as CurrencySymbol
Console.WriteLine("Converted successfully with CultureInfo(en-US): " + decimalValue);
}
else
{
Console.WriteLine("Could not be parsed to decimal");
}
}
Output:
Converted successfully with CultureInfo(en-US): 1000.00
It's worth noting that NumberFormatInfo.InvariantInfo.CurrencySymbol does not return the dollar sign(what i thought) but ¤.
Convert.ToDecimal uses decimal.Parse explicitly this method uses NumberStyles.Number by default.
This is a composite style which includes AllowDecimalPoint but not AllowCurrencySymbol style even if your CurrentCulture's CurrencySymbol is $ and NumberDecimalSeparator is ..
You can use decimal.parse(String, NumberStyles, IFormatProvider) overlaod that takes these as a parameters like;
string s = "$1000.00";
var d = decimal.Parse(s, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint,
CultureInfo.GetCultureInfo("en-US"));
d will be 1000 after parsing.
As per your example. your string value is $1000.00.
This contains a $ sign that's why the compiler is unable to cast string to decimal.
try removing the unusable character by replace. Or try the method below
Regex digitsOnly = new Regex(#"[0-9.]"); // this regex matches only digits and decimal
string decimalnumberstring = digitsOnly.Replace(SomeLabel.Text, "");// replace all non numbers (except decimal) with empty string
then try to convert the string value like below.
if(Convert.ToDecimal(decimalnumberstring) > 1000.00m) { //DO SOMETHING }
hope it helps....
Take the Dollar Sign off of your text first:
Source: $1000
double result = 0M;
String value = SomeLabel.Text.Substring(1);
if (Double.TryParse(value, out result)) {
//
}
return result;
Try this
if(decimal.Parse(SomeLabel.Text) > 1000.00m)
{
}
I have a string which contains a number. It can be one with decimals, followed by either a comma or a dot, depending on the user's locale.
The numbers are actually hundredths and I want to convert them to plain old ints. For example, I want strings "14.5" and "14,5000" to end up as int 1450.
It's probably me, but I can't figure out how to correctly convert this number into an int with a corresponding value when the decimals are separated by a comma. I've tried this:
double valueDouble;
double.TryParse(SpecificTemperatureTextBox.Text, NumberStyles.Any,
CultureInfo.CurrentCulture, out valueDouble);
int valueInt = Convert.ToInt32(valueDouble * 100);
But this comes out wrong sometimes. Here are my results:
TextBox value Expected result Converted result
"14" 1400 1400 (good)
"14.0" 1400 1400 (good)
"14.5" 1450 1450 (good)
"14,0" 1400 14000
"14,5" 1450 14500
Am I not using the System.Globalization correctly when I'm converting? I don't want to replace , with . in the string, because that seems too dirty.
How can I do this?
Maybe safest bet would be to try parse input with both cultures, something like this:
private static int ConvertStringValue(string value)
{
decimal valDouble;
var comma = (NumberFormatInfo)CultureInfo.InstalledUICulture.NumberFormat.Clone();
comma.NumberDecimalSeparator = ",";
comma.NumberGroupSeparator = ".";
var dot = (NumberFormatInfo)CultureInfo.InstalledUICulture.NumberFormat.Clone();
dot.NumberDecimalSeparator = ".";
dot.NumberGroupSeparator = ".";
if (decimal.TryParse(value, NumberStyles.Currency, comma, out valDouble))
{
return Convert.ToInt32(valDouble * 100);
}
else if (decimal.TryParse(value, NumberStyles.Currency, dot, out valDouble))
{
return Convert.ToInt32(valDouble * 100);
}
else
{
return Convert.ToInt32(value);
}
}
Using CurrentCulture will correctly parse numbers with either dot or comma depending on the value of CurrentCulture. But not both simultaneously as in no culture dot and comma are interchangeable.
So, you will have to replace either all commas for dots or vice versa. Then parse with the 'dot separator culture' or 'comma separator culture' setting.
I need convert a String to a decimal in C#, but this string have different formats.
For example:
"50085"
"500,85"
"500.85"
This should be convert for 500,85 in decimal. Is there is a simplified form to do this convertion using format?
Some cultures use a comma to indicate the floating point. You can test this with the following code on an aspx page:
var x = decimal.Parse("500,85");
Response.Write(x + (decimal)0.15);
This gives the answer 501 when the thread culture has been set to a culture that uses the comma as floating point. You can force this like so:
var x = decimal.Parse("500,85", new NumberFormatInfo() { NumberDecimalSeparator = "," });
While decimal.Parse() is the method you are looking for, you will have to provide a bit more information to it. It will not automatically pick between the 3 formats you give, you will have to tell it which format you are expecting (in the form of an IFormatProvider). Note that even with an IFormatProvider, I don't think "50085" will be properly pulled in.
The only consistent thing I see is that it appears from your examples that you always expect two decimal places of precision. If that is the case, you could strip out all periods and commas and then divide by 100.
Maybe something like:
public decimal? CustomParse(string incomingValue)
{
decimal val;
if (!decimal.TryParse(incomingValue.Replace(",", "").Replace(".", ""), NumberStyles.Number, CultureInfo.InvariantCulture, out val))
return null;
return val / 100;
}
This will work, depending on your culture settings:
string s = "500.85";
decimal d = decimal.Parse(s);
If your culture does not by default allow , instead of . as a decimal point, you will probably need to:
s = s.Replace(',','.');
But will need to check for multiple .'s... this seems to boil down to more of an issue of input sanitization. If you are able to validate and sanitize the input to all conform to a set of rules, the conversion to decimal will be a lot easier.
Try this code below:
string numValue = "500,85";
System.Globalization.CultureInfo culInfo = new System.Globalization.CultureInfo("fr-FR");
decimal decValue;
bool decValid = decimal.TryParse(numValue, System.Globalization.NumberStyles.Number, culInfo.NumberFormat, out decValue);
if (decValid)
{
lblDecNum.Text = Convert.ToString(decValue, culInfo.NumberFormat);
}
Since I am giving a value of 500,85 I will assume that the culture is French and hence the decimal separator is ",". Then decimal.TryParse(numValue, System.Globalization.NumberStyles.Number, culInfo.NumberFormat,out decValue);
will return the value as 500.85 in decValue. Similarly if the user is English US then change the culInfo constructor.
There are numerous ways:
System.Convert.ToDecimal("232.23")
Double.Parse("232.23")
double test;
Double.TryParse("232.23", out test)
Make sure you try and catch...
This is a new feature called Digit Grouping Symbol.
Steps:
Open Region and Language in control panel
Click on Additional setting
On Numbers tab
Set Digit Grouping Symbol as custom setting.
Change comma; replace with (any character as A to Z or {/,}).
Digit Grouping Symbol=e;
Example:
string checkFormate = "123e123";
decimal outPut = 0.0M;
decimal.TryParse(checkFormate, out outPut);
Ans: outPut=123123;
Try This
public decimal AutoParse(string value)
{
if (Convert.ToDecimal("3.3") == ((decimal)3.3))
{
return Convert.ToDecimal(value.Replace(",", "."));
}
else
{
return Convert.ToDecimal(value.Replace(".", ","));
}
}