String Formatting to Currency C# - c#

I am new to building web applications in ASP.NET and am trying to display a currency in Kenya Shillings. The symbol for the shilling is KES.
I have this:
<span>
<b>Price: </b><%#:String.Format(new System.Globalization.CultureInfo("sw-KE"), "{0:c}", Item.BeatPrice)%>
</span>
Culture name sourced from http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.80%29.aspx.
However, the price shows as S3,000 instead of KES 3,000.
What do I need to do to format the price correctly?

If the format is not as you expect you can add custom string formatting:
String.Format("KES {0:N3}", Item.BeatPrice)
Hope this works.

It's better not to hardcode the CurrencySymbol, so you should use
var regionInfo = new RegionInfo("sw-KE");
var currencySymbol = regionInfo.ISOCurrencySymbol;
to get the correct CurrencySymbol for your culture.
//edit:
Or you can try this function:
public static string FormatCurrency(decimal value)
{
CultureInfo cultureInfo = Thread.CurrentThread.CurrentUICulture;
RegionInfo regionInfo = new RegionInfo(cultureInfo.LCID);
string formattedCurrency = String.Format("{0} {1:C}", regionInfo.ISOCurrencySymbol, value);
return formattedCurrency.Replace(cultureInfo.NumberFormat.CurrencySymbol, String.Empty).Trim();
}
Which gives you a formatted currency string based on the current UICulture.

If your machine's regional settings are properly set then you can use:
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:c}", Item.BeatPrice));
It will automatically take culture based on your machine's regional settings.

Like Ondrej Svejdar said, there are two symbols, as in $ vs. USD:
var region = new System.Globalization.RegionInfo("sw-KE");
Console.WriteLine(region.CurrencySymbol); // "S"
Console.WriteLine(region.ISOCurrencySymbol); // "KES"
Note: When I ran this on IDEone (which compiles with Mono), the results were unexpected ("KES" and "Kenyan Shilling").

While using String.Format "c" or "C" gives you the currency symbol for specified culture. You are trying to show Currency ISO code for Kenya Shillings. Below code will display exactly what you wanted.
String.Format("{0} {1}", (new RegionInfo("sw-KE")).ISOCurrencySymbol, Item.BeatPrice)
If you don't change culture on your application easy way to do this.
String.Format("{0} {1}", "KES", Item.BeatPrice)

The best practice is to format the String to Currency format {0:C} and change the current thread UICulture or Culture to KES, and ASP.NET is smart enough to display the page accroding to your currunt culuture.
Note:
You can change culture by changing the culture of the browser (you can to do this for development purposes) but best practice change the culture programmatically, for example here I'm change the culture base on user Cookie and mu default culture is en-us like this.
protected override void InitializeCulture()
{
HttpCookie cultureCookie = Request.Cookies["culture"];
if (cultureCookie == null)
{
cultureCookie = new HttpCookie("culture", "en-US");
Response.Cookies.Add(cultureCookie);
}
Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureCookie.Value);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureCookie.Value);
base.InitializeCulture();
}

Related

Get Exact format string with respect to given format specifier

There are lot of format specifier in .net e.g. C for currency, D for decimal.
Lot of defined formats can be here.
How can I get exact format behind format specifier as per given locale.
E.g. (I assume here en-US locale)
GetFormatSpecifierText("C") should return me "$" #,##0.00
GetFormatSpecifierText("F") should return me "#,##0.00
Look at how Culture is used in combination with the format specifiers. I believe you may be looking for the override in the below code from MSDN:
public class userOverrideSample
{
[WebMethod]
public String UserLocalSetting()
{
int i = 100;
// Sets the CurrentCulture to French in France.
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
// Displays i formatted as currency for the CurrentCulture.
// Due to operating system differences, you cannot be sure what currency
// symbol will be used.
return (i.ToString("c"));
}
[WebMethod]
public String OverrideUserSetting()
{
int i = 100;
// Sets the CurrentCulture to French in France.
// Uses the CultureInfo constructor that takes a
// useUserOverride parameter.
// Sets the useUserOverride value to false.
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR", _
false);
// Displays i formatted as currency for the CurrentCulture.
// This will override any user settings and display the euro symbol.
return (i.ToString("c"));
}
}
I write below code to get currency format pattern.
Here, passed param numberFormat as [Currency]#,##0.00 and fr-FR locale; and got # ##0,00 "€" as desire and expected o/p.
static string[] CurrencyPositivePattern = { "$n", "n$", "$ n", "n $" };
static string[] CurrencyNegativePattern = { "($n)", "-$n", "$-n", "$n-", "(n$)",
"-n$", "n-$", "n$-", "-n $", "-$ n",
"n $-", "$ n-", "$ -n", "n- $", "($ n)",
"(n $)" };
internal static string GetCurrencyPattern(System.Globalization.NumberFormatInfo numberFormatInfo, string numberFormat)
{
numberFormat = numberFormat.Replace("[Currency]", string.Empty);
int pos = numberFormatInfo.CurrencyPositivePattern;
int neg = numberFormatInfo.CurrencyNegativePattern;
string currencySymbol = string.Format("\"{0}\"", numberFormatInfo.CurrencySymbol);
string excelPattern = string.Concat(CurrencyPositivePattern[pos].Replace("n", numberFormat).Replace("$", currencySymbol),
";",
CurrencyNegativePattern[neg].Replace("n", numberFormat).Replace("$", currencySymbol));
return excelPattern;
}
Few References that I used for implementation:
https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencynegativepattern(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencypositivepattern(v=vs.110).aspx
As I stucked at specific Currency format for excel, I write Currency specific code. Others formats are easily handled by excel (same also commented by Murray Foxcroft in answer's comment).

How to do Number format in C#

Given number is 282100. I want to display above number like 282.100,00
I am using
String.Format("{0:n}", number)
but I'm getting result like this 282,100.00.
expected=282.100,00.
Is there any way to do this in C#?
If your current culture does not format the number the way you want, you have a couple of options (at least):
Use a known CultureInfo that does format the number the way you want
Create a custom NumberFormatInfo that uses the format you want
In general, I'd say the first option is better. After all, if you have a need to format the number in a specific way, chances are it's because you are doing it for some specific culture. So the best way in that case is to just get the correct CultureInfo object (i.e. by using CultureInfo.GetCultureInfo()) and use that as the IFormatProvider for the formatting.
If for some reason it's not always clear which specific CultureInfo object to get, then you can do it the second way. For example:
decimal number = 282100;
NumberFormatInfo numberFormatInfo =
(NumberFormatInfo)CultureInfo.CurrentCulture.NumberFormat.Clone();
numberFormatInfo.NumberDecimalSeparator = ",";
numberFormatInfo.NumberGroupSeparator = ".";
string text = string.Format(numberFormatInfo, "{0:n}", number);
This particular example allows you to start with a known formatter and then modify it per your specific needs.
Finally, if you believe your current culture should be formatting the number the way you want but it isn't doing that, then it is best to figure out why it's not doing that, rather than overriding the current culture. Usually, you want to use the default formatting for any text displayed to the user or received from the user, so that the program works correctly regardless of culture.
You can create your own number format and use that to get desired results. Something like this:
NumberFormatInfo customFormat = new NumberFormatInfo(); ;
customFormat.NumberGroupSeparator = ".";
customFormat.NumberDecimalSeparator = ",";
customFormat.NumberGroupSizes = new int[1]{3};
decimal someNumber = 123456789.123m;
string number = someNumber.ToString("N",customFormat);
You can customize the format by providing a new IFormatProvider:
var num = 282100;
// Output using a custom formatter:
Console.WriteLine(num.ToString("N",
new NumberFormatInfo{ NumberDecimalSeparator = ",", NumberGroupSeparator = "."}));
// Or if you want to save the formatted string:
var str = String.Format(new NumberFormatInfo {NumberDecimalSeparator = ",",
NumberGroupSeparator = "."}, "{0:N}", num);
Console.WriteLine(str);

ToLongDateString() not working

string[] splitDate = DateOfBirth.ToLongDateString().Split(new char[] { ',', ' ' });
foreach (string s in splitDate)
{
Console.Write(s);
}
For input like "15/08/1991", it gives the output "Thursday August 15 1991" on my machine but gives output "August 15 1991" on another machine.
The code works fine on my system but fails on another system due to above reason. Any help is appreciated.
This happens, because:
The string returned by the ToLongDateString method is culture-sensitive
as it is stated here.
In order you fix it you have to specify the CurrentCulture property of the CurrentTread.
Thread.CurrentThread.CurrentCulture = new CultureInfo("...");
However, that will affect everything that relies on the culture in your code.
Here is a list of predefined cultures, that you could use.
Soner's comment is correct. Check out the documentation on how to set the culture using CurrentCulture. However, from your code it seems that you just need a string that contains a date and you can do that easily with DateOfBirth.Day, DateOfBirth.Month, DateOfBirth.DayOfWeek etc.
that is because of the culture and region settings of windows.
if u want to do it you can specify the culture you want to use as parameter.
DateTime.Now.ToString(new CultureInfo("en-GB"));
you can specify your date format as a second parameter as well :)
This is an old thread but this will be helpful for someone stil searching:
var CurrentCulture = Thread.CurrentThread.CurrentCulture; //Store the current culture
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("el-GR"); //Set a new culture
String FullString = MyDate.ToLongDateString(); //Get your string
Thread.CurrentThread.CurrentCulture = CurrentCulture; //Restore the environment.
Hope this helps.

How to convert "12,4" to decimal en-Us culture

I have a decimal value ("133,3") stored in string column in the database, in norway culture.
after that user changed the regional setting to english-Us. when I convert "133,3" to decimal using CultureInfo.InvariantCulture, getting invalid value or error.
is there any best way to handle this scenario in C# application?
regards,
Anand
Regardless of the system culture, if you specify CultureInfo.InvariantCulture you won't be able to parse "133,3" as a decimal to 133.3. The same is true for US English.
You could just specify a Norwegian culture when parsing the value (using the overload of decimal.TryParse which takes an IFormatProvider), or (preferrably) change the field in the database to reflect the real data type (a decimal number) instead.
Do you referred to Convert.ToDecimal(), it says like
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
string[] values = { "123456789", "12345.6789", "12 345,6789",
"123,456.789", "123 456,789", "123,456,789.0123",
"123 456 789,0123" };
CultureInfo[] cultures = { new CultureInfo("en-US"),
new CultureInfo("fr-FR") };
foreach (CultureInfo culture in cultures)
{
Console.WriteLine("String -> Decimal Conversion Using the {0} Culture",
culture.Name);
foreach (string value in values)
{
Console.Write("{0,20} -> ", value);
try {
Console.WriteLine(Convert.ToDecimal(value, culture));
}
catch (FormatException) {
Console.WriteLine("FormatException");
}
}
Console.WriteLine();
}
}
}
If you know the culture that was in use when persisting the value, you can use it when parsing it, i.e.:
Convert.ToDecimal("133,3", System.Globalization.CultureInfo.GetCultureInfo("no"));
Of course, you are probably better off changing how the data is stored in the database, to use a floating point number of some form.
Convert.ToDouble(textBox2.Text, new CultureInfo("uk-UA")).ToString(new CultureInfo("en-US"));
This solves your problem: .ToString(New CultureInfo("en-US"))
Hope it's helpful
double _number = 12536,8;
CultureInfo usCulture = new CultureInfo("en-US");
return _number.ToString("N", us);
used below code to fix my issue. I just hard coded the previous currency decimal part. may not be generic. but solved my problem.
public static decimal? ToDecimal1(this string source)
{
CultureInfo usCulture = new CultureInfo("en-US");
if (string.IsNullOrEmpty(source.Trim1()))
return null;
else
return Convert.ToDecimal(source.Replace(",", ".").Trim(), usCulture);
}

String.Format Same Code Different View

I have a code like this;
GridView1.FooterRow.Cells[11].Text = String.Format("{0:c}", sumKV)
In my computer this code gives a result like that;
But when I upload this code to my virtual machine it looks like this;
TL means Turkish Liras. But I don't want to show the currency. I just want numbers.
I also don't want to change the formating of numbers. (Like 257.579,02)
How can I only delete TL in this code?
I would use this:
var cultureWithoutCurrencySymbol =
(CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureWithoutCurrencySymbol.NumberFormat.CurrencySymbol = "";
GridView1.FooterRow.Cells[11].Text =
String.Format(cultureWithoutCurrencySymbol, "{0:c}", sumKV).Trim();
Background:
This will still keep the currency formatting for the current culture, it just removes the currency symbol.
You can save this special culture somewhere, so you don't have to create it every time you need to format your values.
UPDATE:
Now it even compiles... ;-)
Added a Trim(), because there is still a space after the formated number.
Another option is to turn off the currency symbol entirely for the current thread:
private static NumberFormatInfo SetNoCurrencySymbol()
{
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
NumberFormatInfo LocalFormat = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
NumberFormatInfo ret = culture.NumberFormat;
LocalFormat.CurrencySymbol = "";
culture.NumberFormat = LocalFormat;
// Add the culture to the current thread
Thread.CurrentThread.CurrentCulture = culture;
return ret;
}
That way you will change less code. You can always change it back afterwards:
NumberFormatInfo origNumberFormat = SetNoCurrencySymbol();
string x = String.Format("{0:c}", 55);
CultureInfo.CurrentCulture.NumberFormat = origNumberFormat;
string y = String.Format("{0:c}", 55);
Because you are using String.Format with a format string only, sumKV is formatted according to the UI Culture actually used in your application.
GridView1.FooterRow.Cells[11].Text = String.Format("{0:c}", sumKV),
To get rid with currency symbol, use InvariantCulture in String.Format this way :
String.Format(CultureInfo.InvariantCulture, "{0:c}", sumKV);
If you don't want to show currency then don't use the currency formatting code - {0:c}.
Perhaps try something like the following:
GridView1.FooterRow.Cells[11].Text = String.Format("{0:G}", sumKV);
See this article - String.Format doubles

Categories