c# format price to database with variant decimal places - c#

I need a function to retrieve the price well formated to be inserted into database. The database only accepts dot as decimal separator and cannot have thousands separator.
1,000.25 -> is not valid
1000.25 -> is valid
1000,25 -> is valid (but will be converted ',' to '.')
However not always the columns have 2 decimal places, some columns can have 5 decimal places.
public static double MoneyToDatabase(string value, int decimal_places)
{
if(string.IsNullOrEmpty(value) == true)
return 0.00;
value = value.Replace(",", "."); // converts the comma into dot
string cardinal = "##";
if(decimal_places > 2)
for(int i = 3; i <= decimal_places; i++)
cardinal += "#";
return Convert.ToDouble(string.Format("{0:0." + cardinal + "}", value));
}
Problems and questions I'm facing:
Is there any way (in Linq or something) - besides loop - to add the remaining #?
MoneyToDatabase("15,00", 2) returns 1500, should return 15.00
MoneyToDatabase("15,00", 5) returns 1500, should return 15.00000
I have no clue what '0:' means

you can use converts like below:
float.Parse("1,000.25", NumberStyles.AllowThousands);
float.Parse("1000.25", NumberStyles.AllowThousands);
1000,25 you can replace it ;).
Note that if you use different cultures do that with invariant cultures.

Solved.
The actual problem was the CultureInfo and I found out I can use "F2", "F3" and that will retrieve the decimal places as I want.
public static string MoneyToDatabase(string value, int decimal_places)
{
if(string.IsNullOrEmpty(value) == true)
return "0.00";
value = value.Replace(",", ".");
string format = "F" + decimal_places;
double valueAsDouble;
double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out valueAsDouble);
// It sets again a comma in the string and must be replaced
return valueAsDouble.ToString(format).Replace(",", ".");
}

Related

How to compare currency or alphanumeric values in C#

The value that extracted from the application is in string format for ex. "$0.38". So, I segregated each character in the given string using IsDigit then appended them together using string builder. The digit can also be alphanumeric like "12,365.23 AS". Is there a way to recover only numeric part (along with the decimal) from the given string.
But Output I receive is "38" instead of "0.38". I also want to compare that the given string value lies between the upperLimit and lowerLimit provided.
Please let me know how to proceed with the same.
string Value = "$0.38";
int upperLimit = 2500;
int lowerLimit = 50000;
StringBuilder sb = new StringBuilder();
//sb.Append(someString);
foreach (char amin in Value)
{
if (System.Char.IsDigit(amin))
{
sb.Append(amin);
}
}
int compareVal = Convert.ToInt32(sb.ToString());
Console.WriteLine("value for comparision" + " " + compareVal);
The best way is using one of the overloads of decimal.Parse:
string Value = "$0.38";
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
decimal dd=decimal.Parse(Value, System.Globalization.NumberStyles.AllowCurrencySymbol|System.Globalization.NumberStyles.AllowDecimalPoint,culture);
Note the use of NumberStyles enum.That way you can control exaclty the parsing.
There are two reasons why you will get 38:
StringBuilder looks like "038", since "." is not a digit (just like "$").
Convert.ToInt32(...) returns an integer which doesn't allow decimal digits.
The better data type for currencies is decimal, a high precision floating point data type so to say.
Try
var amount = decimal.Parse(Value , NumberStyles.Currency)
var isInLimit = upperLimit <= amount && amount <= lowerLimit; // i guess you swapped upper and lower limit btw. ;)
instead.
Edit
In order to use the NumberStyles-Enumeration, you will have to use tha correct namespace in your file:
using System.Globalization;
You are omitting the decimal point and you are not using a decimal data type to hold the converted value. The real way to go is to convert the currency string to a decimal number:
CultureInfo usCulture = new CultureInfo("en-US)";
decimal amount = decimal.Parse(Value, NumberStyles.Currency, usCulture);
You can then perform a proper numeric comparison:
if (amount <= upperLimit && amount >= lowerLimit)
....
I first marked the question as a duplicate, but then changed my mind. I still think it is very much related to: Convert any currency string to double

Converting a number from a string to an int with decimals separated by comma or dot

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.

How i can convert string values in formats "1.123" and "1,123" to double by single double.TryParse?

I have an incoming source of string values representing double values with "." and "," delimiter and my program would run on PCs with different settings of delimiter ("," or ",")
Which way can I convert it with single line without trying first convert ".", then if fail, try ","?
I tried some combinations like that:
string dot_val = "1.12";
string non_dot_val = "1,12";
double dot_double = 0, non_dot_double = 0;
bool dot_res = double.TryParse(dot_val, NumberStyles.Any, CultureInfo.CurrentCulture, out dot_double);
bool non_dot_res = double.TryParse(non_dot_val, NumberStyles.Number | NumberStyles.AllowCurrencySymbol, CultureInfo.CurrentCulture, out non_dot_double);
But one of the attempts to convert is always fail.
If tell it shortly, I need an universal function to convert "." or "," delimited double values into double
Well, the current culture tells you whether . or , is the decimal separator. If you want your function to parse both formats, you need to pass in a culture that has the respective separator. In your example:
public double UniveralParse(string value)
{
double result;
// If we can not parse the "." format...
if (!double.TryParse(value, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result))
// And also can not parse the "," format...
if (!double.TryParse(value, NumberStyles.Any, CultureInfo.GetCultureInfo("de-DE"), out result))
// we throw an exception
throw new ArgumentException("value is not in expected format!");
// Otherwise we can return the value
return result;
}
The easiest way is to replace ',' by '.' and parse the result using the invariant culture setting:
double.TryParse(
dot_val.Replace(',','.'),
NumberStyles.Any,
CultureInfo.InvariantCulture,
out dot_double);
The only limitation of this is that you shouldn't have grouping in your number (like 123,000.45)

How to split a string based on every third character regardless of what the character is in c# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
.NET String.Format() to add commas in thousands place for a number
I am trying to add commas to a number for the presentation layer and need to cast and then split the number on every third character in order to join on a ','.
So if i have a string like this
546546555
desired output:
546,546,555
Other times, the number could be longer or shorter:
254654
desired output:
254,654
Is it possible to split in this manner then join with a comma?
tahnks!
EDIT:
Hi Everyone,
Thanks very much for your help.
To add to this post I also found a way to do this in SQL:
SUBSTRING(CONVERT(varchar, CAST(NumItems AS money), 1), 0, LEN(CONVERT(varchar, CAST(NumDocs AS money), 1)) - 2) as [NumDocs]
Rather than splitting the string manually, you should convert it to a number (or leave it as a number), and call the ToString method with the appropriate formatting:
Example
int value = 546546555;
string displayValue = value.ToString("#,#");
See this MSDN page for different format values:
C - Currency format
D - Decimal format
E - Scientific format
F - Fixed point format
G - General format
N - Number format
P - Percent format
R - Round trip format
X - Hexadecimal format
You should do this by converting your string to an integer, using Parse or ideally TryParse and use string formatting to display it:
var str = "546546555";
var formatted = String.Empty;
int value = 0;
if(int.TryParse(str,out value))
{
formatted = value.ToString("#,#");
}
Live example: http://rextester.com/FHO11833
Assuming you aren't only trying to output numbers, here's a quick function that I believe would do what you are after:
string splitter(string tosplit, int num, string splitstring)
{
string output = "";
for (int i = 0; i < tosplit.Length; i += num)
if (i + num < tosplit.Length)
output += tosplit.Substring(i, num) + ",";
else
output += tosplit.Substring(i);
return output;
}
Here, the output of splitter("546546555", 3, ",") would be 546,546,555
This would not be ideal for numbers though, as the other answers would cover this case perfectly.
Not very good code, but it works.
public static string GetString(string val, int number)
{
List<string> res = new List<string>();
res.Add("");
int counter = 0, i = 0;
while (i < val.Length)
{
while (res[counter].Length < number && i < val.Length)
{
res[counter] += val[i];
i++;
}
res.Add("");
counter++;
}
return string.Join(",", res.Where(r => !string.IsNullOrEmpty(r)));
}
val - your input string
number - number of characters you want to split, equals to 3 in your case
Gene S and Dan seem to have the answer IMHO. The nice thing about using the built in formatting is that you can write localizable code. For example, the "," is the numeric group separator in the US, but the "." is used in Spain.
var val = 12345678;
CultureInfo c = CultureInfo.CurrentCulture;
Application.CurrentCulture = new CultureInfo("EN-us");
var s = String.Format("{0:#,#}", val);
Application.CurrentCulture = new CultureInfo("ES-es");
var i = String.Format("{0:#,#}", val);
Application.CurrentCulture = c;

Is it possible to implement the script in code behind

I have a javascript code which conver the amount in to US format the same i would like to have in code behind can any one help me..
<script type="text/javascript">
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
sign = (num == (num = Math.abs(num)));
num = Math.floor(num*100+0.50000000001);
cents = num%100;
num = Math.floor(num/100).toString();
if(cents<10)
cents = "0" + cents;
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+
num.substring(num.length-(4*i+3));
return (((sign)?'':'-') + '$' + num + '.' + cents);
}
</script>
Or if there is any easier method tell me. My actual requirement is to sum the two given amounts in the text boxes and to display the amount in 3rd text box.
For example if i have my 1st value as 123.12 by the above script i will get the display in my text box as $123.12 and second as same to $123.12 the output should be $246.23
can any one help me
There is a standard formatting for currency:
double n = 12345.67;
Console.WriteLine(n.ToString("C2", CultureInfo.GetCultureInfo("en-US")));
Ouptut:
$12,345.67
The standard for negative currency values is however to display it within parentheses, so if you want a negative sign instead you have to modify the culture:
CultureInfo info = new CultureInfo("en-US");
info.NumberFormat.CurrencyNegativePattern = 1;
double n = -12345.67;
Console.WriteLine(n.ToString("C2", info));
Ouptut:
-$12,345.67
If 123.12 + 123.12 = 246.23 then your customers might not be to happy
What type is num actually? It looks like it's just a number, but you're converting it to string, removing $ and , signs, just to add them later?
You can use decimal.ToString(string format) method, something like this should give you proper results:
static string Format(decimal x)
{
return x.ToString("$#,0.00", System.Globalization.CultureInfo.InvariantCulture);
}
//Usage:
string currencyFormatedNumber = Format(-41023.43M); //returns -$41,023.43
You could use something like this:
static string Format(decimal x)
{
return x.ToString("C", System.Globalization.CultureInfo.GetCultureInfo("en-us"));
}
which is used to format currency, but it will format negative numbers as they should be formatted ($100.00) means -100.00 dollars, which differs from your code.

Categories

Resources