9

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?

Ken Jackson
  • 163
  • 3
  • 6

3 Answers3

3

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.

Steven Robbins
  • 26,441
  • 7
  • 76
  • 90
  • Cool! This also fixes timespan formatting, ie {0:mm\:ss} in arabic for some reason. With digit substitution a formatting error occurs. – Wouter Jun 26 '14 at 12:38
  • 3
    It has been stated on MSDN that `DigitSubstitution` doesn't have any effect any is reserved for future use: https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.digitsubstitution.aspx. How does this solution even work? – Isaac Aug 10 '15 at 13:23
  • 3
    This code does fails with "InvalidOperationException: Instance is read-only." unless your code sets `CurrentCulture` to be non-read only (like `...CurrentThread.CurrentCulture = new CultureInfo("fr-fr")` ) and as @Isaac pointed out even after you get code to run `DigitSubstitution` has no effect on result... Working sample could be useful i.e. www.ideone.com ... – Alexei Levenkov Sep 24 '15 at 16:36
1

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]);
}
tjsmith
  • 729
  • 7
  • 21
0
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!!!

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
Lusine
  • 17
  • 1