I have a problem with String.Format. The following code formats the string correctly apart from the first integer. Current culture is set to Iraqi arabic (ar-IQ):
int currentItem= 1;
string of= "من";
int count = 2;
string formatted = string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}", currentItem, of, count);
The text is formatted right to left and the 2 is converted to an arabic digit, but the 1 isn't.
Any ideas?
The default behaviour for converting numeric values is "Context", which basically means if a number is proceeded by Arabic they display in Arabic (or another "non-Latin" character), if they're not then they display in "standard" European numbers.
You can change that behaviour quite easily though:
var culture = CultureInfo.CurrentCulture;
culture.NumberFormat.DigitSubstitution = DigitShapes.NativeNational; // Always use native characters
string formatted = string.Format(culture, "{0:d}{1:d}{2:d}", currentItem, of, count);
That should work as you expect - more details on MSDN.
I couldn't get either of the other answers to work. This worked for me:
string sOriginal = "1 of 2";
var ci = new CultureInfo("ar-IQ", false);
var nfi = ci.NumberFormat;
string sNative = ReplaceWesternDigitsWithNativeDigits(sOriginal, nfi).Replace("of", "من");
...
private static string ReplaceWesternDigitsWithNativeDigits(string s, NumberFormatInfo nfi)
{
return s.Replace("0", nfi.NativeDigits[0])
.Replace("1", nfi.NativeDigits[1])
.Replace("2", nfi.NativeDigits[2])
.Replace("3", nfi.NativeDigits[3])
.Replace("4", nfi.NativeDigits[4])
.Replace("5", nfi.NativeDigits[5])
.Replace("6", nfi.NativeDigits[6])
.Replace("7", nfi.NativeDigits[7])
.Replace("8", nfi.NativeDigits[8])
.Replace("9", nfi.NativeDigits[9]);
}
var culture = CultureInfo.CurrentCulture;
culture.NumberFormat.DigitSubstitution = DigitShapes.NativeNational;
does not work,
but the following works:
var culture = new CultureInfo("ar-SA");
culture.NumberFormat = new NumberFormatInfo();
Thread.CurrentThread.CurrentCulture = culture;
Thanks for the hint!!!
Related
I'm a doubt when formatting a number of type double.
I would like it to be from 250000.0 to 250.000
With dot and not comma
Another example: from 26000 to 26.000
You can use The Numeric ("N") Format Specifier.
To force specific thousands separator, specify NumberGroupSeparator.
var num = 250000.0;
NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;
nfi.NumberGroupSeparator = ".";
var numString = num.ToString("N0", nfi);
Try this:
var value = 250000.0;
var text = value.ToString("N0", CultureInfo.GetCultureInfo("de-DE"));
This gives 250.000 as you asked.
You can simply replace the culture code, "de-DE", with one that gives you the output you need.
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).
If I set Format in [Region and Language] to US...
CultureInfo cul = CultureInfo.CurrentCulture;
string decimalSep = cul.NumberFormat.CurrencyDecimalSeparator;//decimalSep ='.'
string groupSep = cul.NumberFormat.CurrencyGroupSeparator;//groupSep=','
sFormat = string.Format("#{0}###", groupSep);
string a = double.Parse(12345).ToString(sFormat);
The result is: 12,345 (is correct)
But if I set the format in [Region and Language] to VietNam, then the result is: 12345
The result should be 12.345.
Can you help me? Thanks.
You are helping too much. The format specifier is culture insensitive, you always use a comma to indicate where the grouping character goes. Which is then substituted by the actual grouping character when the string is formatted.
This formats correctly:
CultureInfo cul = CultureInfo.GetCultureInfo("vi-VN"); // try with "en-US"
string a = double.Parse("12345").ToString("#,###", cul.NumberFormat);
You should actually use "#,#" to ensure it still works in cultures that have a uncommon grouping. It wasn't clear from the question whether that mattered or not so I punted for "#,###"
Try something like this:
var value = 8012.34m;
var info = System.Globalization.CultureInfo.GetCultureInfo("vi-VN");
Console.WriteLine(String.Format(info, "{0:c}", value));
The result is:
8.012,34 ₫
Oh, and with the value 12345 the result is 12.345,00 ₫.
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
I feed a textbox a string value showing me a balance that need to be formatted like this:
###,###,###,##0.00
I could use the value.ToString("c"), but this would put the currency sign in front of it.
Any idea how I would manipulate the string before feeding the textbox to achieve the above formatting?
I tried this, without success:
String.Format("###,###,###,##0.00", currentBalance);
Many Thanks,
If the currency formatting gives you exactly what you want, clone a NumberFormatInfo with and set the CurrencySymbol property to "". You should check that it handles negative numbers in the way that you want as well, of course.
For example:
using System;
using System.Globalization;
class Test
{
static void Main()
{
NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
nfi = (NumberFormatInfo) nfi.Clone();
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
nfi.CurrencySymbol = "";
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
}
}
The other option is to use a custom numeric format string of course - it depends whether you really want to mirror exactly how a currency would look, just without the symbol, or control the exact positioning of digits.
string forDisplay = currentBalance.ToString("N2");
Have you tried:
currentBalance.ToString("#,##0.00");
This is the long-hand equivalent of:
currentBalance.ToString("N2");
string result=string.Format("{0:N2}", value); //For result like ### ### ##.##
You can do this with the group separator and the section separator, like this:
currentBalance.ToString("#,0.00;(#,0.00)");
This does not account for culture variances like the answer from #JonSkeet would, but this does mimic decimal place, rounding, thousands separation, and negative number handling that en-US culture currency format produces using a single custom format string.
.NET Fiddle Demo
var result = currentBalance.ToString("C").Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol, "");
CultureInfo cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencySymbol = "Rs.";
Thread.CurrentThread.CurrentCulture = cultureInfo;
decimal devimalValue = 3.45M;
this.Text = devimalValue.ToString("C2"); //Rs.3.45
This may be overkill, but it rounds, formats...
#helper TwoDecimalPlaces(decimal? val)
{
decimal x = 0;
decimal y = 0;
string clas = "text-danger";
if (val.HasValue)
{
x = (decimal)val;
if (val > 0)
{
clas = "";
}
}
y = System.Math.Round(x, 2);
IFormatProvider formatProvider = new System.Globalization.CultureInfo(string.Empty);
<span class="#clas">#string.Format("{0:N2}", y)</span>
}
This simple solution works for me with US currency.
If not needing international currency support use this and replace the $ with the currency symbol(s) to be removed:
// for USD
string result = currentBalance.ToString("C").Replace("$", "")
or
// for EUR
string result = currentBalance.ToString("C").Replace("€", "")