34

I want to display Persian(Farsi) numbers on views. For example I calculated a date and converted it to Jalali calendar but how can I display it by Persian numbers?

Farnad Tohidkhah
  • 1,229
  • 1
  • 10
  • 19

13 Answers13

25

Another way to show numbers with Persian font is the use of following Helper Class:

public class FormatHelper {

    private static String[] persianNumbers = new String[]{ "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };


    public static String toPersianNumber(String text) {
        if (text.length() == 0) {
            return "";
        }
        String out = "";
        int length = text.length();
        for (int i = 0; i < length; i++) {
        char c = text.charAt(i);
        if ('0' <= c && c <= '9') {
            int number = Integer.parseInt(String.valueOf(c));
            out += persianNumbers[number];
        }
        else if (c == '٫') {
            out += '،';
        }
        else {
            out += c;
        }

        return out;
    }
}

Save this class as UTF8 format and use it like the following code

FormatHelper.toPersianNumber(numberString);
Iman Marashi
  • 5,593
  • 38
  • 51
Farnad Tohidkhah
  • 1,229
  • 1
  • 10
  • 19
  • if you calculate on numbers it would make it hard. cause when you want calculation you must convert them back. but using font no convert and de-convert is needed. – Hojat Modaresi Jul 18 '16 at 05:25
15

By using Typeface class the font type of a view can be changed to Farsi font so the numbers can be shown by Farsi fonts :

Typeface typeface = Typeface.createFromAsset(getAssets(), "FarsiFontName.ttf");
myView.setTypeface(typeface);
Farnad Tohidkhah
  • 1,229
  • 1
  • 10
  • 19
5

set the locale to Arabic, Egypt

int i = 25;
NumberFormat nf = NumberFormat.getInstance(new Locale("ar","EG"));
nf.format(i);
SMahdiS
  • 930
  • 13
  • 33
4

You can create custom view and attach farsi font on that, finally you can use that on xml views.most farsi font dont have english number in character map and you can use simply that without any problem. for example :

public class TextViewStyle extends TextView {

    public TextViewStyle(Context context) {
        super(context);
        init(context, null, 0);
    }


    public TextViewStyle(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init(context, attrs, 0);
    }


    public TextViewStyle(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle){
        try {
            TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.TextViewStyle, defStyle, 0);
            String str = a.getString(R.styleable.TextViewStyle_fonttype);
            switch (Integer.parseInt(str)) {
                case 0:
                    str = "fonts/byekan.ttf";
                    break;
                case 1:
                    str = "fonts/bnazanin.ttf";
                    break;
                case 2:
                    str = "fonts/btitr.ttf";
                    break;
                case 3:
                    str = "fonts/mjbeirut.ttf";
                    break;
                case 4:
                    str = "fonts/bnazanin_bold.ttf";
                    break;
                default:
                    str = "fonts/bnazanin.ttf";
                    break;
            }
            setTypeface(FontManager.getInstance(getContext()).loadFont(str));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

attr.xml :

<declare-styleable name="TextViewStyle">
    <attr name="selected_background" format="integer"/>
    <attr name="fonttype">
        <enum name="byekan" value="0"/>
        <enum name="bnazanin" value="1"/>
        <enum name="btitr" value="2"/>
        <enum name="mjbeirut" value="3"/>
        <enum name="bnazaninBold" value="4"/>
    </attr>
</declare-styleable>
  • In this case we need just persian numbers, not all characters, so i suggest create an array and put persian numbers manually. – Manian Rezaee Oct 31 '15 at 12:03
4

Kotlin Version via Extension Property

If you want to show every type of numbers (e.g. Int, Double, Float, etc) in Persian or Arabic digits, using these extension properties really helps:


PersianUtils.kt

/**
 * @author aminography
 */

val Number.withPersianDigits: String
    get() = "$this".withPersianDigits

val String.withPersianDigits: String
    get() = StringBuilder().also { builder ->
        toCharArray().forEach {
            builder.append(
                when {
                    Character.isDigit(it) -> PERSIAN_DIGITS["$it".toInt()]
                    it == '.' -> "/"
                    else -> it
                }
            )
        }
    }.toString()

private val PERSIAN_DIGITS = charArrayOf(
    '0' + 1728,
    '1' + 1728,
    '2' + 1728,
    '3' + 1728,
    '4' + 1728,
    '5' + 1728,
    '6' + 1728,
    '7' + 1728,
    '8' + 1728,
    '9' + 1728
)


Usage:

println("Numerical 15   becomes: " + 15.withPersianDigits)
println("Numerical 2.75 becomes: " + 2.75.withPersianDigits)

println("Textual 470  becomes: " + "470".withPersianDigits)
println("Textual 3.14 becomes: " + "3.14".withPersianDigits)

Result:

Numerical 15   becomes: ۱۵
Numerical 2.75 becomes: ۲/۷۵

Textual 470  becomes: ۴۷۰
Textual 3.14 becomes: ۳/۱۴
aminography
  • 21,986
  • 13
  • 70
  • 74
3

The simple and correct way is to use Locale and String.format. You can simply use a Persian font for the view in case the default font does not support Persian numbers. Here's how I would do it.

Locale locale = new Locale("fa");
return String.format(locale, "%04d", year) + "/" + 
       String.format(locale, "%02d", month) + "/" + 
       String.format(locale, "%02d", day);

You could also use PersianCaldroid library, which not only provides you with simple APIs like PersianDate.toStringInPersian() but also lets you have Persian DatePicker and CalendarView.

Dariush Malek
  • 914
  • 1
  • 6
  • 14
3

The simplest and easiest way is using NumberFormat :

NumberFormat numberFormat = NumberFormat.getInstance(new Locale("fa","IR"));
textView.setText(numberFormat.format(15000))
ParSa
  • 1,118
  • 1
  • 13
  • 17
2

try this while Typing For EditText:

 public static void edtNumE2P(final EditText edt) {
    edt.addTextChangedListener(new TextWatcher() {

      @Override
      public void onTextChanged(CharSequence s, int pstart, int pbefore, int pcount) {
//        for (String chr : new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}) {
        for (char chr : "0123456789".toCharArray()) {
          if (s.toString().contains("" + chr)) {
            edt.setText(MyUtils.numE2P(edt.getText().toString()));
            edt.setSelection(edt.getText().length());
          }
        }
      }


      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after) {

      }


      @Override
      public void afterTextChanged(Editable s) {
      }
    });
  }

And Try This too :

    public static String numE2P(String str, boolean reverse) {
    String[][] chars = new String[][]{
      {"0", "۰"},
      {"1", "۱"},
      {"2", "۲"},
      {"3", "۳"},
      {"4", "۴"},
      {"5", "۵"},
      {"6", "۶"},
      {"7", "۷"},
      {"8", "۸"},
      {"9", "۹"}
    };

    for (String[] num : chars) {
      if (reverse) {
        str = str.replace(num[1], num[0]);
      } else {
        str = str.replace(num[0], num[1]);
      }
    }
//    Log.v("numE2P", str);
    return str;
  }
Criss
  • 755
  • 7
  • 22
2

you can use Time4J to display date and use ChronoFormatter to display :

ChronoFormatter<PersianCalendar> formatter= ChronoFormatter.setUp(PersianCalendar.axis(), PERSIAN_LOCALE)
.addPattern("dd", PatternType.CLDR).build();
// it will display day :  ۲۴

or

.addPattern("dd MMMM", PatternType.CLDR).build();
// مرداد ۲۴

and with defining patterns you can choose how date display : ChronoFormatter

eisbehr
  • 12,243
  • 7
  • 38
  • 63
Vahid Rajabi
  • 191
  • 3
  • 3
  • For Android, I would rather use Time4A (sister project). There are also several ways to show Farsi numbers, either by choosing a suitable locale for Iran, or by modification of the formatter like this: `chronoFormatter.with(Attributes.NUMBER_SYSTEM, NumberSystem.ARABIC_INDIC_EXT)` – Meno Hochschild Aug 17 '18 at 15:15
1

You can use the following method to display the number in Persian :

 public String NumToPersion(String a){
    String[] pNum =new String[]{"۰","۱","۲","۳","۴","۵","۶","۷","۸","۹" };
    a=a.replace("0",pNum[0]);
    a=a.replace("1",pNum[1]);
    a=a.replace("2",pNum[2]);
    a=a.replace("3",pNum[3]);
    a=a.replace("4",pNum[4]);
    a=a.replace("5",pNum[5]);
    a=a.replace("6",pNum[6]);
    a=a.replace("7",pNum[7]);
    a=a.replace("8",pNum[8]);
    a=a.replace("9",pNum[9]);
   return a;
}
1

Simply do it in kotlin for unsigned integers

fun toPersian(n:Int) : String{
val p="۰۱۲۳۴۵۶۷۸۹"
return n.toString().trim().map{
    p[it.toString().trim().toInt()]
}.joinToString()
}
txt_view?.text=toPersian(12087)//۱۲۰۸۷
babak
  • 73
  • 1
  • 4
1

To manage the application language (English / Persian), the font used in the application must convert and display the numbers in Persian and English correctly.

That's why we use the setTypeface() method:

public class MyTextView extends TextView {
        public MyTextView (Context context, AttributeSet attrs) {
            super(context, attrs);
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/iransans_fa_number_regular.ttf");
            setTypeface(typeface);
        }
    }

And when the language of the application changes, we change the font used in MyTextView :

public static String iranSansRegular;

public static void setLocale(Resources res, Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences("Configuration", 0);
        String appLang = sharedPreferences.getString("appLanguage", Locale.getDefault().getLanguage());

        if (appLang.equals("fa")) {
            iranSansRegular = "fonts/iransans_fa_number_regular.ttf";
        } else {
            iranSansRegular = "fonts/iransans_en_number_regular.ttf";
        }

        Locale myLocale = new Locale(appLang);
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        Locale.setDefault(myLocale);
        conf.setLayoutDirection(myLocale);
        res.updateConfiguration(conf, dm);
    }

And use the iranSansRegular to set typeface:

public class MyTextView extends TextView {
        public MyTextView (Context context, AttributeSet attrs) {
            super(context, attrs);
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), iranSansRegular);
            setTypeface(typeface);
        }
    }
ZIRES
  • 276
  • 3
  • 10
-1

you must add the persian standard keyboard in windows and change to this keyboard when you want to type persian digits and words. It is work for me