Как я могу преобразовать английские цифры в арабские цифры?

У меня есть этот код С#, например,

DateTime.Now.ToString("MMMM dd, yyyy");

Теперь текущая тема загружает арабскую культуру. Итак, результат такой:

???? 19, 2010

Но я не хочу, чтобы "2010" и "19" были на английском языке (также известный как латинские или западно-арабские цифры) - я хочу, чтобы восточно-арабские цифры, такие как "٢".

Я пытался

DateTime.Now.ToString("MMMM dd, yyyy", CultureInfo.GetCultureInfo("ar-lb"));

дал тот же результат. Так есть идеи?

Ответ 1

В этом обходном пути (просто перечислите все культуры, в которых вы хотите использовать эти цифры в массиве строк):

private static class ArabicNumeralHelper
{
    public static string ConvertNumerals(this string input)
    {
        if (new string[] { "ar-lb", "ar-SA" }
              .Contains(Thread.CurrentThread.CurrentCulture.Name))
        {
            return input.Replace('0', '\u06f0')
                    .Replace('1', '\u06f1')
                    .Replace('2', '\u06f2')
                    .Replace('3', '\u06f3')
                    .Replace('4', '\u06f4')
                    .Replace('5', '\u06f5')
                    .Replace('6', '\u06f6')
                    .Replace('7', '\u06f7')
                    .Replace('8', '\u06f8')
                    .Replace('9', '\u06f9');
        }
        else return input;
    }
}

Затем используйте метод, для всех ваших strings вы хотите иметь "центральные арабские цифры", например:

DateTime.Now.ToString().ConvertNumerals();

Ответ 2

В качестве быстрого теста я написал это, чтобы перечислить все сокращения, которые не имеют "2010" в году:

        foreach (var ci in 
            from c in CultureInfo.GetCultures(CultureTypes.AllCultures)
            where !c.IsNeutralCulture
            let date = DateTime.Now.ToString("MMMM dd, yyyy", c)
            where !date.Contains("2010")
            orderby c.Name
            select new {c.Name, date})
        {
            Console.WriteLine("{0} : {1}", ci.Name, ci.date);
        }

результаты:

ar-SA : ربيع الأول 05, 1431
dv-MV : ربيع الأول 06, 1431
prs-AF : ربيع الأول 06, 1431
ps-AF : ربيع الأول 06, 1431
th-TH : กุมภาพันธ์ 19, 2553

Чтобы преобразовать числа в арабский текст, это выглядит как этот проект "NumToArabicString" . Однако это не похоже на что-либо, встроенное в инфраструктуру .net.

Ответ 3

Единственное решение - это вручную преобразовать цифры.

Вы можете использовать массив CurrentCulture.NumberFormat.NativeDigits вместо того, чтобы явно предоставлять символы Unicode для поддержки любых других языков в дополнение к цифрам на арабском языке, но поскольку встроенная поддержка классов, поддерживающих культуру, таких как DateTime, кажется не реализовано или что-то еще.

Ответ 4

Попробуйте следующее:

public static string ToIndicDigits(this string input)
{
        return input.Replace('0', '\u0660')
                .Replace('1', '\u0661')
                .Replace('2', '\u0662')
                .Replace('3', '\u0663')
                .Replace('4', '\u0664')
                .Replace('5', '\u0665')
                .Replace('6', '\u0666')
                .Replace('7', '\u0667')
                .Replace('8', '\u0668')
                .Replace('9', '\u0669');
    }
}

Ответ 5

Вы можете использовать класс Windows.Globalization.NumberFormatting.NumeralSystemTranslator для перевода между латинскими и любыми поддерживаемыми цифровыми системами. Чтобы перевести на арабский язык, установите для свойства NumeralSystem значение "Arab", затем вы можете вызвать метод TranslateNumerals.

В качестве альтернативы вы можете просто использовать Windows.Globalization.DateTimeFormatting.DateTimeFormatter класс.

Ответ 6

Мы используем арабские цифры на английском языке. Таким образом, то, что вы видите, - это правильное и возможное поведение.

Ответ 7

Я использовал подход @Marcel B/обходной путь, поскольку столкнулся с той же проблемой, что и первоначальный вопрос.

В моем случае это для "ar-KW" Культура. Единственное отличие состоит в том, что я использую NumberFormat.NativeDigits, который уже является частью CultureInfo.

Вы можете проверить это следующим образом (в зависимости от текущего сценария потока):

Thread.CurrentThread.CurrentCulture.NumberFormat.NativeDigits

Итак, код будет выглядеть так:

private static class ArabicNumeralHelper
{
    public static string ConvertNumerals(this string input)
    {
        CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;

        if (new string[] { "ar-lb", "ar-SA" }
              .Contains(cultureInfo.Name))
        {
            return input.Replace('0', cultureInfo.NumberFormat.NativeDigits[0])
                        .Replace('1', cultureInfo.NumberFormat.NativeDigits[1])
                        .Replace('2', cultureInfo.NumberFormat.NativeDigits[2])
                        .Replace('3', cultureInfo.NumberFormat.NativeDigits[3])
                        .Replace('4', cultureInfo.NumberFormat.NativeDigits[4])
                        .Replace('5', cultureInfo.NumberFormat.NativeDigits[5])
                        .Replace('6', cultureInfo.NumberFormat.NativeDigits[6])
                        .Replace('7', cultureInfo.NumberFormat.NativeDigits[7])
                        .Replace('8', cultureInfo.NumberFormat.NativeDigits[8])
                        .Replace('9', cultureInfo.NumberFormat.NativeDigits[9]);
        }
        else return input;
    }
}

Надеюсь, это поможет.