I am using the following to display an amount:
String.Format("{0:C}", item.Amount)
This display £9.99
which is okay, but what if I want the application to be able to control the currency and to be able to change the currency to day
$9.99
How do I change the currency format via code
The currency symbol is defined by CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol. The property is read/write but you will probably get an exception if you try to change it, because NumberFormatInfo.IsReadOnly will be true...
Alternatively, you could format the number by explicitly using a specific NumberFormatInfo :
NumberFormatInfo nfi = (NumberFormatInfo)CultureInfo.CurrentCulture.NumberFormat.Clone();
nfi.CurrencySymbol = "$";
String.Format(nfi, "{0:C}", item.Amount);
Specify the culture in the call to Format:
decimal value = 123.45M;
CultureInfo us = CultureInfo.GetCultureInfo("en-US");
string s = string.Format(us, "{0:C}", value);
CultureInfo info = new CultureInfo (System.Threading.Thread.CurrentThread.CurrentCulture.LCID);
info.NumberFormat.CurrencySymbol = "EUR";
System.Threading.Thread.CurrentThread.CurrentCulture = info;
Console.WriteLine (String.Format ("{0:C}", 45M));
or
NumberFormatInfo info = new NumberFormatInfo ();
info.CurrencySymbol = "EUR";
Console.WriteLine (String.Format (info, "{0:C}", 45M));
If you change the displayed currency of an amount, then you are changing its unit of measurement too. £1 <> €1 <> $1. Are you absolutely sure of the business requirement here?
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 can not convert query string to decimal.
In this example, when I control Request.QueryString["Amount"] value, It is 32.52 After the below code works, The Amount values is 3252M like that. How can I easily do this?
decimal Amount= 0;
if (Request.QueryString["Amount"] != null)
Amount = Convert.ToDecimal(Request.QueryString["Amount"]);
Convert.ToDecimal uses your current culture settings by default.
I strongly suspect your CurrentCulture's NumberDecimalSeparator property is not ., but NumberGroupSeparator property is .
That's why your program thinks this is a thousands separator, not decimal separator and it parses as a 3252, not 32.52.
As a solution you can use a culture which have . as a NumberDecimalSeparator like InvariantCulture, or you can .Clone your current culture and set it's NumberDecimalSeparator to . 1
Amount = Convert.ToDecimal(Request.QueryString["Amount"], CultureInfo.InvariantCulture);
or
var culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Amount = Convert.ToDecimal("32.52", culture);
1: If your current culture's thousands separator is not . already. Otherwise, you need to change it as well. Both property can't have the same values for any culture
I think you are having problems with the Culture as stated in the rpevious answer. You may want to try using different cultures:
RetVal = decimal.Parse(Request.QueryString["Amount"], CultureInfo.CurrentCulture);
Then I would try:
RetVal = decimal.Parse(Request.QueryString["Amount"], CultureInfo.InvariantCulture);
I have code that was originally written for an English language market where the decimal separator is "." so it's expecting numeric values as strings to use "." as the separator. But we now have users in other places, e.g., places in Europe where the decimal separator is ",".
So, in the context of my software (really just the current thread) I want to override the decimal separator for the current language to be "." even if it defaults to something else.
I tried
String sep = ".";
NumberFormatInfo nfi1 = NumberFormatInfo.CurrentInfo;
nfi1.NumberDecimalSeparator = sep;
But I get an "Instance is read-only" exception on the third line. Apparently NumberFormatInfo is not writable. So how DO you set the current language's decimal separator to something other than its default?
You need to create a new culture and you can use the current culture as a template and only change the separator.
Then you must set the current culture to your newly created one as you cannot change the property within current culture directly.
string CultureName = Thread.CurrentThread.CurrentCulture.Name;
CultureInfo ci = new CultureInfo(CultureName);
if (ci.NumberFormat.NumberDecimalSeparator != ".")
{
// Forcing use of decimal separator for numerical values
ci.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = ci;
}
You can use the Clone() method on the NumberFormatInfo instance, which will create a mutable version (i.e. IsReadOnly = false). You are then able set the currency symbol and/or other number format options:
string sep = ".";
NumberFormatInfo nfi1 = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
nfi1.NumberDecimalSeparator = sep;
I have a simple problem with decimal parsing. The following code works fine on my computer but when I publish the project on the server (VPS, Windows Server 2008 R2 standard edition) I get the error "Input string was in incorrect format." Any ideas what's wrong?
I store that parsed number in the MySQL DB table - the column type is DECIMAL(10, 4)
Source Code:
CultureInfo nonInvariantCulture = new CultureInfo("en-AU"); //or pl-PL
nonInvariantCulture.NumberFormat.NumberDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture = nonInvariantCulture;
string toConvert = ("3,4589").Replace(",", "."); //it's an example
decimal parsed = decimal.Parse(toConvert);
If you know that the string representation of the number uses comma as the decimal separator you can parse the value using a custom NumberFormatInfo:
var number = "3,4589";
var numberFormatInfo = new NumberFormatInfo { NumberDecimalSeparator = "," };
var value = Decimal.Parse(number, numberFormatInfo);
You can also use an existing CultureInfo for a culture that you know will work like pl-PL but I think this is easier to understand.
If on the other hand the format of the number is 3.4589 you can simply use CultureInfo.InvariantCulture which you can consider a kind of "default" culture based on en-US:
var number = "3.4589";
var value = Decimal.Parse(number, CultureInfo.InvariantCulture);
You can build a custom NumberFormatInfo to parse your value
something on these lines
NumberFormatInfo numinf = new NumberFormatInfo();
numinf.NumberDecimalSeparator= ",";
decimal.Parse("3,4589", numinf);
I guess for a work around the below code will sort it out the problem.
decimal parsed = decimal.Parse(toConvert, CultureInfo.InvariantCulture);
I have a double number as string. The number is
202.667,40
Which is 202667.4
How can I parse this string to get the value like: Double.Parse("202.667,40",?what here), or any other method to get the value would be great. Thanks
First, you need to know which culture this number is from, then:
CultureInfo culture = new CultureInfo("de"); // I'm assuming german here.
double number = Double.Parse("202.667,40", culture);
If you want to parse using the current thread culture, which by default is the one set for the current user:
double number = Double.Parse("202.667,40", CultureInfo.CurrentCulture);
I think i have found a solution which does not require a culture. Using a NumberFormatInfo you can force a format, no matter the culture:
// This is invariant
NumberFormatInfo format = new NumberFormatInfo();
// Set the 'splitter' for thousands
format.NumberGroupSeparator = ".";
// Set the decimal seperator
format.NumberDecimalSeparator = ",";
Then later:
System.Diagnostics.Debug.WriteLine(double.Parse("202.667,40", format)));
Outputs:
202667,4
Of course, this output (inner toString()) might differ per Culture(!)
Note that changing the input to "202,667.40" will result in a parse error, so the format should match your expected input.
Hope this helps someone..
Instead of having to specify a locale in all parses, I prefer to set an application wide locale, although if string formats are not consistent across the app, this might not work.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");
Defining this at the begining of your application will make all double parses expect a comma as the decimal delimiter.
You could use Double.Parse(your_number, CultureInfo.CurrentCulture) and set CurrentCulture accordingly with Thread.CurrentThread.CurrentCulture.
Example:
Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");
then later
Double.Parse(your_number, CultureInfo.CurrentCulture);
Note that if you explicitly assign the culture to the CurrentThread, it only applies to that thread.
var val=double.Parse( yourValue, CultureInfo.InvariantCulture);
http://www.erikschierboom.com/2014/09/01/numbers-and-culture/
For more flexibility you can set NumberDecimalSeparator
string number = "202.667,40";
double.Parse(number.Replace(".", ""), new CultureInfo(CultureInfo.CurrentCulture.Name) {NumberFormat = new NumberFormatInfo() {NumberDecimalSeparator = ","}});
Double.Parse("202.667,40", new System.Globalization.CultureInfo("de-DE"));
Instead of de-DE use whatever culture the string is in.