C# Convert back from thousand separator to int - c#

I have a code that makes an int to a thousend separator but when I try to save this value in the text box to the database I want to remove the space between. I could not do this with replace(" ","").
YearTB.Text = (String.Format(culture, "{0:n0}", Int32.Parse(YearTB.Text)));
What is in the box is for example "536 396" but the space between is not an " ". its the effect of the thousand seperator. How can I return it back to int. "536396".

If you just want to convert to a string without the thousands rather than to an int:
string result = text.Replace(culture.NumberFormat.NumberGroupSeparator, "");
This assumes that culture is the CultureInfo with which the number was formatted using a thousand separator.
Alternatively if you want to convert to an int, you can use int.Parse() directly and specify that you want to allow the thousands separator (which I think is a better approach):
int result = int.Parse(text, NumberStyles.AllowThousands, culture);

Try this
string str = "536 396";
str = Regex.Replace(str, #"\s", "");

Related

C# string to Decimal On All style or Culture

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.

Contains doen't check in the date range

I have a date range come like this,
string ActualReleaseDates ="7/8/2016, 7/9/2016, 7/11/2016,7/3/2016,7/10/2016,7/17/2016,7/24/2016,7/31/2016";
string NewsReleasedDate ="07/11/2016";
I want to check NewsReleaseDate is inside the ActualReleaseDates
But in the following code it return as a false.
if (ActualReleaseDates.Split(',').Contains(NewsReleasedDate.TrimStart(new Char[] { '0' })))
{
//some code here
}
The immediate problem is that after splitting your ActualReleaseDates string, there isn't an entry of "7/11/2016"... instead, there's an entry of " 7/11/2016"... note the space.
But more fundamentally, just trimming the start of NewsReleasedDate won't help if the value is something like "07/08/2016"... what you should be doing is handling these values as dates, rather than as strings:
Split ActualReleaseDates by comma, then parse each value (after trimming whitespace) in an appropriate format (which I suspect is M/d/yyyy) so that you get a List<DateTime>.
Parse NewsReleasedDate in the appropriate format, which I suspect is MM/dd/yyyy, so you get a DateTime.
See whether the parsed value from the second step occurs in the list from the first step.
(I'd personally recommend using Noda Time and parsing to LocalDate values, but I'm biased...)
Fundamentally, you're trying to see whether one date occurs in a list of dates... so make sure you get your data into its most appropriate representation as early as possible. Ideally, avoid using strings for this at all... we don't know where your data has come from, but if it started off in another representation and was converted into text, see if you can avoid that conversion.
The white space problem. You can use trim() and ' 7/11/2016' will be '7/11/2016'
var ActualReleaseDates = "7/8/2016, 7/9/2016, 7/11/2016,7/3/2016,7/10/2016,7/17/2016,7/24/2016,7/31/2016";
var NewsReleasedDate = "07/11/2016";
var splitActualReleaseDates = ActualReleaseDates.Split(',').Select(x => x.Trim());
if (splitActualReleaseDates.Contains(NewsReleasedDate.TrimStart(new Char[] { '0' })))
{
}
You can use linq to convert your strings into DateTime objects and compare them instead of strings
string ActualReleaseDates ="7/8/2016,7/9/2016,7/11/2016,7/3/2016,7/10/2016,7/17/2016,7/24/2016,7/31/2016";
string NewsReleasedDate ="07/11/2016";
var releaseDates = ActualReleaseDates.Split(',').Select(x => DateTime.Parse(x));
var newsReleased = DateTime.Parse(NewsReleaseDate);
if (releaseDates.Contains(newsReleased))
{
//some code here
}
please note that DateTime is parsed respectively to the current Culture. You can use DateTime.ParseExact if you want to specify exact date format.
You can Prase to DateTime before doing the query like this:
(I think this is the most accurate and guaranteed way to compare dates)
Func<string, DateTime> stringToDate = s => DateTime.ParseExact(s.Trim(), "M/d/yyyy",
CultureInfo.InvariantCulture);
DateTime newReleaseDateTime = stringToDate(NewsReleasedDate);
bool result = ActualReleaseDates.Split(',').Select(x => stringToDate(x))
.Contains(newReleaseDateTime);
It returns false because of the date 07/11/2016 stored in NewsReleasedDate is stored as string with a '0' at the begining. And in the ActualReleaseDates string you have white spaces between the ',' and numbers.
Try to rewrite theese strings like this :
ActualReleaseDates ="7/8/2016,7/9/2016,7/11/2016,7/3/2016,7/10/2016,7/17/2016,7/24/2016,7/31/2016"; // white spaces removed.
and the variable like this :
NewsReleasedDate ="7/11/2016"; // 0 removed
This is my code example :
string ActualReleaseDates = "7/8/2016,7/9/2016,7/11/2016,7/3/2016,7/10/2016,7/17/2016,7/24/2016,7/31/2016";
string NewsReleasedDate = "7/11/2016";
string[] dates = ActualReleaseDates.Split(',');
Console.WriteLine(dates.Contains(NewsReleasedDate));
This is not the best way to compare dates, you can use Date class which is usefull to do this kind of comparations.

Conversion of C# decimal values of System.Array in into string

I have a very strange problem in C# application. The problem is consistent, but only on one remote computer. The data below contains decimal numbers. I perform the following simplified operation:
Array data = (Array)get_data(); // array of decimals
StringBuilder sb = new StringBuilder();
sb.Append(data.GetValue(0));
string s = sb.ToString();
This converts numbers like 14.62 into "14,62", i.e comma instead of dot. Later, when I parse this string into double, it generates errors. How to prevent this?
Please note, that I don't have access to that remote computer. I can only adjust the program's code, and then send a new installer.
StringBuilder sb = new StringBuilder();
sb.Append(((double)data.GetValue(0)).ToString(CultureInfo.InvariantCulture));
See: http://msdn.microsoft.com/en-us/library/shxtf045(v=vs.110).aspx
You are getting the different output because of the remote computer's culture. Some culture uses , as decimal separators and some uses .. To override that you have to call ToString with CultureInfo.InvariantCulture. You can also use the following one liner which would give you the same thing.
string s = string.Join(",",
data.OfType<decimal>()
.Select(r=> r.ToString(CultureInfo.InvariantCulture)));
(I assumed that you needed a delimiter separated string for your data elements, since you were using StringBuilder)
I had a similar issue I cloned the Culture Invariant( makes it en-US)
private string ConvertPriceFormat(double amount)
{
string price = string.Empty;
// NumberFormatInfo of InvariantCulture thousandseparator = "," DecimalSeparator="."
NumberFormatInfo nfi = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
// make Changes for the Injection
nfi.NumberGroupSeparator = "";
// Format the price with the defined format
price = amount.ToString("n", nfi);
return price;
}
Just need to change it to go from string to double

Convert double to string, keep format - C#

Hi all. I have a double number (Ex: 0.000006). I want convert it to string type. But result is "6E-06". I dont want it, i want 0.000006".Thanks you so much
double a = 0.000006;
string resultString = a.toString();
I don't know many number after "." character
It's simple that if you want to show a number as exactly as what it looks, we can cast it to decimal and use the default ToString() like this:
var s = ((decimal)yourNumber).ToString();
//if yourNumber = 0.00000000000000000000000006
//just append the M after it:
var s = (0.00000000000000000000000006M).ToString();
Please check this article and find the format which suits your needs: http://www.csharp-examples.net/string-format-double/
Looks like this one is good enough:
String.Format("{0:0.00}", 123.4567);
Use String.Format() with the format specifier.
double a = 0.000006;
string formatted = String.Format("{0:F6}", a);
Try with the Roundtrip 'R' format specifier:
double a = 0.000006;
string resultString = a.ToString("R");
Double Rate_USD = Convert.ToDouble(txtRateUsd.Text);
string Rate_USD = txtRateUsd.Text;

Convert.ToInt32() conditional formatting according to string with comma

string str = e.Row.Cells[index].Text;
int value = Int32.Parse(str, NumberStyles.AllowThousands, NumberFormatInfo.InvariantInfo);
if (value >= 100)
e.Row.Cells[index].BackColor = System.Drawing.Color.Green;
Cell values are 168,88 - 125,45 - 75,3
After parsing str returns 16888 - 12545 - 753 , so all of the cells are set as green
how can i compare real values.?
You are using NumberFormatInfo.InvariantInfo. This treats , as thousands separator.
Are you sure this is the correct one? Did you mean to use something like CultureInfo.GetCulture("fr-FR"), where the , is the decimal separator?
Additionally, if you need to preserve the decimal part, why parse to an integer?
This should work better for you:
decimal.Parse(str, NumberStyles.AllowThousands, CultureInfo.GetCulture("fr-FR"));
I think what you're looking for is:
int value = Int32.Parse(str, NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
The NumberFormatInfo tells the Parse function HOW the input should be interpreted. The InvariantInfo reads as Gets the default read-only NumberFormatInfo that is culture-independent (invariant) from msdn.

Categories

Resources