C# Price Validation using regular expression other way - c#

As part of my work,I need to read price values from Excel sheet . I need to implement
Prices: Non-numeric characters in Price not allowed
price should be valid number for price like int,decimal,double etc like 10,10.00,10,233 valid, -10,-10.00,-10,2333.00 etc are invalid
Prices: Price format (dots, comma's, decimals)
Zero and negative price values are not allowed
Need to check price value type (number type like int,float,decimal etc but will save in database in money format)
What datatype I should we choose for Price ? decimal or double or anyother ? In database I took database field type as money.

I do not think you need any regex if you just need to validate price numbers in C#.
I'd suggest using Decimal type, here you can find why. The Decimal class contains a static TryParse method that can be used to validate numbers as valid decimal numbers. Here is a slightly modified example from MSDN (I decided to go with InvariantCulture, but it depends on whether your DB contains currencies in EN-US format or not):
var validated = false;
decimal number;
// Parse currency value using current culture.
var value = "1,097.63";
var style = System.Globalization.NumberStyles.Number;
var culture = System.Globalization.CultureInfo.InvariantCulture;
if (!Decimal.TryParse(value, style, culture, out number))
if (number > 0) // Check if the value is not negative or zero
validated = true;

Related

How to get the format string for a specified currency and culture

I have SSRS reports that display currency amounts. They need to be both culture aware and currency aware. Some reports show different currencies in the same table. I have no trouble with culture awareness. It's currency formatting that's the trouble. Importantly, when I export to Excel, the values in these currency fields must be sortable as numbers. That means the cell values must be numbers, so I cannot use the normal .ToString("C", culture) functions that so many other posts end up with. I need to keep the numeric value in the field and to apply .NET's format string to the number (e.g. "'$'#,0.00;('$'#,0.00)"). This way, Excel will treat the value as a number for sorting purposes but display the correctly formatted currency.
Is it possible to use code to modify a NumberFormatInfo instance and then somehow return the string value of the formatter, such as "'€'#,0.00;('€'#,0.00)"?
var numberFormat = new CultureInfo("en-US").NumberFormat;
numberFormat.CurrencySymbol = "€";
return numberFormat.GetCurrencyFormatString(); //this is an imaginary function that I need to return "'€'#,0.00;('€'#,0.00)"
I have tried programmatically setting the currency symbol based on the currency information of each row. As far as I know, SSRS does not allow me to use an Expression to set the currency symbol. It only offers a dropdown list.
My users don't like it when I show the currency code (e.g. USD, CAD), so I'm stuck with showing the symbol (e.g. $, CA$).
As far as I can tell, you'll need to manually construct this format string using the CultureInfo class.
Using the docs on CurrencyPositivePattern and CurrencyNegativePattern (see here and here), I've put together something that works but might need some tweaking:
string GetCurrencyFormat(CultureInfo culture)
{
//we'll use string.Format later to replace {0} with the currency symbol
//and {1} with the number format
string[] negativePatternStrings = { "({0}{1})", "-{0}{1}", "{0}-{1}", "{0}{1}-", "({1}{0})",
"-{1}{0}", "{1}-{0}", "{1}{0}-", "-{1} {0}", "-{0} {1}",
"{1} {0}-", "{0} {1}-", "{0} -{1}", "{1}- {0}", "({0} {1})",
"({1} {0})" };
string[] positivePatternStrings = { "{0}{1}", "{1}{0}", "{0} {1}", "{1}{0}" };
var numberFormat = culture.NumberFormat;
//Generate 0's to fill in the format after the decimal place
var decimalPlaces = new string('0', numberFormat.CurrencyDecimalDigits);
//concatenate the full number format, e.g. #,0.00
var fullDigitFormat = $"#{numberFormat.CurrencyGroupSeparator}0{numberFormat.CurrencyDecimalSeparator}{decimalPlaces}";
//use string.Format on the patterns to get the positive and
//negative formats
var positiveFormat = string.Format(positivePatternStrings[numberFormat.CurrencyPositivePattern],
numberFormat.CurrencySymbol, fullDigitFormat);
var negativeFormat = string.Format(negativePatternStrings[numberFormat.CurrencyNegativePattern],
numberFormat.CurrencySymbol, fullDigitFormat);
//finally, return the full format
return $"{positiveFormat};{negativeFormat}";
}
This returns $#,0.00;($#,0.00) for en-US, £#,0.00;-£#,0.00 for en-GB, for example.

string format money , [duplicate]

I need to display a number with commas and a decimal point.
Eg:
Case 1 : Decimal number is 432324 (This does not have commas or decimal points).
Need to display it as: 432,324.00.
Not: 432,324
Case 2 : Decimal number is 2222222.22 (This does not have commas).
Need to display it as: 2,222,222.22
I tried ToString("#,##0.##"), but it is not formatting it correctly.
int number = 1234567890;
number.ToString("#,##0.00");
You will get the result 1,234,567,890.00.
Maybe you simply want the standard format string "N", as in
number.ToString("N")
It will use thousand separators, and a fixed number of fractional decimals. The symbol for thousands separators and the symbol for the decimal point depend on the format provider (typically CultureInfo) you use, as does the number of decimals (which will normally by 2, as you require).
If the format provider specifies a different number of decimals, and if you don't want to change the format provider, you can give the number of decimals after the N, as in .ToString("N2").
Edit: The sizes of the groups between the commas are governed by the
CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes
array, given that you don't specify a special format provider.
Try with
ToString("#,##0.00")
From MSDN
*The "0" custom format specifier serves as a zero-placeholder symbol. If the value that is being formatted has a digit in the position where the zero appears in the format string, that digit is copied to the result string; otherwise, a zero appears in the result string. The position of the leftmost zero before the decimal point and the rightmost zero after the decimal point determines the range of digits that are always present in the result string.
The "00" specifier causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used. For example, formatting 34.5 with "00" would result in the value 35.*
I had the same problem. I wanted to format numbers like the "General" format in spreadsheets, meaning show decimals if they're significant, but chop them off if not. In other words:
1234.56 => 1,234.56
1234 => 1,234
It needs to support a maximum number of places after the decimal, but don't put trailing zeros or dots if not required, and of course, it needs to be culture friendly. I never really figured out a clean way to do it using String.Format alone, but a combination of String.Format and Regex.Replace with some culture help from NumberFormatInfo.CurrentInfo did the job (LinqPad C# Program).
string FormatNumber<T>(T number, int maxDecimals = 4) {
return Regex.Replace(String.Format("{0:n" + maxDecimals + "}", number),
#"[" + System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + "]?0+$", "");
}
void Main(){
foreach (var test in new[] { 123, 1234, 1234.56, 123456.789, 1234.56789123 } )
Console.WriteLine(test + " = " + FormatNumber(test));
}
Produces:
123 = 123
1234 = 1,234
1234.56 = 1,234.56
123456.789 = 123,456.789
1234.56789123 = 1,234.5679
Try with
ToString("#,##0.###")
Produces:
1234.55678 => 1,234.556
1234 => 1,234
For Razor View:
$#string.Format("{0:#,0.00}",item.TotalAmount)
CultureInfo us = new CultureInfo("en-US");
TotalAmount.ToString("N", us)
Your question is not very clear but this should achieve what you are trying to do:
decimal numericValue = 3494309432324.00m;
string formatted = numericValue.ToString("#,##0.00");
Then formatted will contain: 3,494,309,432,324.00
All that is needed is "#,0.00", c# does the rest.
Num.ToString("#,0.00"")
The "#,0" formats the thousand separators
"0.00" forces two decimal points
If you are using string variables you can format the string directly using a : then specify the format (e.g. N0, P2, etc).
decimal Number = 2000.55512016465m;
$"{Number:N}" #Outputs 2,000.55512016465
You can also specify the number of decimal places to show by adding a number to the end like
$"{Number:N1}" #Outputs 2,000.5
$"{Number:N2}" #Outputs 2,000.55
$"{Number:N3}" #Outputs 2,000.555
$"{Number:N4}" #Outputs 2,000.5551
string Mynewcurrency = DisplayIndianCurrency("7743450.00");
private string DisplayIndianCurrency(string EXruppesformate)
{
string fare = EXruppesformate;
decimal parsed = decimal.Parse(fare, CultureInfo.InvariantCulture);
CultureInfo hindi = new CultureInfo("en-IN");
// string text = string.Format(hindi, "{0:c}", parsed);if you want <b>Rs 77,43,450.00</b>
string text = string.Format(hindi, "{0:N}", parsed); //if you want <b>77,43,450.00</b>
return ruppesformate = text;
}
For anyone looking at this now, and getting the "No overload for method 'ToString' takes 1 argument" when using:
TotalNumber.ToString("N")
My solution has been to use :
TotalNumber.Value.ToString("N")
I often get stuck on this when working directly inside an MVC View, the following wasn't working:
#Model.Sum(x => x.Number).ToString("N")
Whereas this works:
#Model.Sum(x => x.Number).Value.ToString("N")

How to convert decimal to money format

I'm trying to convert a number so it looks like the formatting in money.
I need to take 258000 and make it 2,580.00 or 25000 and make it 250.00 or 360 and make it 3.60
This is what I'm using but it's adding the ".00" at the end of all numbers making 2500 2500.00 but it should be 25.00.
Value = string.Format("{0:##,###.00}", Convert.ToDecimal(Value));
It seems to me that you're just missing the fact that you can divide the user's input by 100 after parsing it:
using System;
class Program
{
static void Main(string[] args)
{
string input = "2500";
decimal cents = decimal.Parse(input); // Potentially use TryParse...
decimal dollars = cents / 100m;
string output = dollars.ToString("0.00");
Console.WriteLine(output); // 25.00
}
}
Note that there are complicated cultural rules around how currency values should be displayed - I would suggest using the C format specifier, using a CultureInfo which is like whatever the users are expecting, but with the NumberFormatInfo.CurrencySymbol set to an empty string.
You should also consider which culture to use when parsing the user's input - it can significantly affect the results if they decide to use grouping separators or decimal separators. Will they always be entering an integer? If so, parse it as an integer too.
double valueOriginal = 260;
Response.Write( (valueOriginal / 100).ToString("C"));
260 = (206/100)
then
(260/100).ToString("C");

Double.TryParse with a string having two decimal points

This might be a simple and basic question, but, thought of confirming with you. Im in the process of writing code to validate the entered text information is double or not. In my code, below is the line to validate the speed value taken from a text box.
double _mSpeed = 0.0;
if (!Double.TryParse(txtboxSpeed.Text, out _mSpeed))
throw new Exception("Input value for Speed is invalid !!!");
But, if user provides 4.4.4 in speed text box, TryParse is parsing the text string to 444.0 value. Im wondering this is correct or not. Please share your thoughts whether if user enters any value with 2 decimal points, should it not parse to double or what is the expected behavior.
In cultures where . is the decimal separator, like en-US and the invariant culture, 4.4.4 is not valid. In other cultures, like de-DE, , is the decimal separator and . is the thousands separator, so 4.4.4 is 444 (with nonstandard, but acceptable, thousands separators inserted, like 4,4,4 in the en-US culture).
double.Parse("4.4.4", new CultureInfo("de-DE")) // 444
double.Parse("4.4.4", new CultureInfo("en-US")) // FormatException: Input string was not in a correct format.
double.Parse("4,4,4", new CultureInfo("en-US")) // 444
double.Parse("4,4,4", new CultureInfo("de-DE")) // FormatException: Input string was not in a correct format.
The issue could be that the Culture currently used by your application treats comma as decimal separator instead of period. You can force it to use period as decimal separator by setting culture to en-GB.
double _mSpeed = 0.0;
if (!Double.TryParse(txtboxSpeed.Text,NumberStyles.Any,CultureInfo.CreateSpecificCulture("en-GB"), out _mSpeed))
throw new Exception("Input value for Speed is invalid !!!");
Instead of creating a CultureInfo for a specific culture that uses your number format (e.g., "en-US"), you can also just specify NumberFormatInfo.InvariantInfo.
double val1, val2;
bool b1 = double.TryParse("4.4.4", NumberStyles.Any, NumberFormatInfo.InvariantInfo, out val1);
bool b2 = double.TryParse("4,444.4", NumberStyles.Any, NumberFormatInfo.InvariantInfo, out val2);
In the above code b1 is set to false but b2 succeeds and val2 is 4444.4.

How do I validate a price (number) textbox?

I have a Windows forms application written in C#.
I am looking for a way to validate my price textBox so that it only accepts prices in a double format e.g. allowing 0.01 & 1200.00 but provides an error when the user enters characters.
I would except the code to looks similar to
String price = tbx_price.Text.Trim();
if price is not a number
{
error message
}
else{
...
What method could I use to check if the price string contains only numbers? Please note that I require the user to be able to use decimal places so the '.' character should be allowed.
Use decimal.TryParse :
decimal d;
if (!decimal.TryParse(price, out d)){
//Error
}
And if you also want to validate the price (145.255 is invalid):
if (!(decimal.TryParse(price, out d)
&& d >= 0
&& d * 100 == Math.Floor(d*100)){
//Error
}
You can test this using decimal.TryParse().
For example:
decimal priceDecimal;
bool validPrice = decimal.TryParse(price, out priceDecimal);
If you can't be sure that the thread culture is the same as the user's culture, instead use the TryParse() overload which accepts the culture format (also the number format which you can set to currency):
public bool ValidateCurrency(string price, string cultureCode)
{
decimal test;
return decimal.TryParse
(price, NumberStyles.Currency, new CultureInfo(cultureCode), out test);
}
if (!ValidateCurrency(price, "en-GB"))
{
//error
}
Besides using the answer marked as accepted in order to avoid the problem with culture about prices, you can always use this
Convert.ToDouble(txtPrice.Text.Replace(".", ","));
Convert.ToDouble(txtPrice.Text.Replace(",", "."));
this will depend how you manage your convertion in your app.
PS: I could not comment the answer because i do not have the neccesary reputation yet.

Categories