Formatting numbers is straight forward in Java. Many developers overlook this aspect of localization. Numeric systems vary around the world, and even more importantly the delimiters and separators vary. ICU4J provides even more capabilities
You want to format and parse integer values.
The Java NumberFormat class makes formatting and parsing a number is localized manner easy and efficient. Simple specify the locale when retrieving the NumberFormat instance.
To format and parse a number in Hindi:
//Get a locale. Hindi in India here.
ULocale hindi = new ULocale("hi_IN");
//Get an instance of an integer format.
NumberFormat nf = NumberFormat.getIntegerInstance(hindi);
//format and output. The decimal is cut off and rounded.
String f = nf.format(1234234234.556);
System.out.println(f);
//Parse the value. We must handle the potential ParseException
try {
System.out.println(nf.parse("१,२३,४२,३४,२३५"));
} catch (ParseException e) {
e.printStackTrace();
}
The output:
१,२३,४२,३४,२३५
1234234235
You want to format and parse decimal values.
Localized formatting of decimal values is easy in Java. It can be accomplished by passing the number into the getInstance method on the NumberFormat class. Then simply call format and parse.
To format and parse a decimal value for Arabic:
//Get a locale. We use Arabic without a country here.
ULocale arabic = new ULocale("ar");
//Get a decimal formatter instance
NumberFormat nf = NumberFormat.getInstance(arabic);
//format and output
String f = nf.format(123456.789);
System.out.println(f);
//Parse the value. We must handle the potential ParseException
try {
System.out.println(nf.parse("١٢٣٬٤٥٦٫٧٨٩"));
} catch (ParseException e) {
e.printStackTrace();
}
The output :
١٢٣٬٤٥٦٫٧٨٩
123456.789
You want to format and parse percent values.
The Java NumberFormat class makes it easy to create a localized format for a percent value. Simply pass the locale when retrieving your instance. The format will see 1 as 100% and .1 as 10%.
To format and parse a percent value for Brazillian Portuguese:
//Get a locale. In this case Portuguese in Brazil
ULocale pt = new ULocale("pt_BR");
//Get an instance of a percent formatter
NumberFormat nf = NumberFormat.getPercentInstance(pt);
//format and output. 1 == 100% and .5 = 50%
String f = nf.format(.78);
System.out.println(f);
//Parse the value. We must handle the potential ParseException
try {
System.out.println(nf.parse("78%"));
} catch (ParseException e) {
e.printStackTrace();
}
The output:
78%
0.78
You want to format and parse localized currency values.
Currency formatting at its most basic is straight forward in Java programming. Simply retrieve a currency instance of the NumberFormat class and format your number.
To format a currency for Japanese for Japan:
//Get a locale.
Locale ja = new Locale("ja","JP");
//Get a currency instance
NumberFormat nf = NumberFormat.getCurrencyInstance(ja);
//format and output. Notice the rounding is limited to two place on the output. This is
//Governed by the currency
String f = nf.format(123456.789);
System.out.println(f);
//Parse the value. We must handle the potential ParseException
try {
System.out.println(nf.parse("¥123,457"));
} catch (ParseException e) {
e.printStackTrace();
}
The output:
¥123,457
123457
Currencies have a rounding increment that is also important. A US dollar has cents, and so a currency should be rounded two decimal places. A Japanese Yen should be rounded to the nearest integer. If you specify a currency other than the default for the locale the rounding will reflect the locale and not the currency.
You want to format an ordinal number like "1st" or "2nd".
Java programmers can handle ordinal number formatting by leveraging ICU4J's RuleBasedNumberFormat class.
An ordinal number is a number like "1st" "2nd" etc.
To format an ordinal number:
//Get a RuleBasedNumberFormat appropriate for English ordinal format
RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ULocale.ENGLISH,RuleBasedNumberFormat.ORDINAL);
//Format the number
System.out.println(rbnf.format(21));
The output:
21st
You want to convert a spelled out number to a Number.
Parsing a formatted number in Java takes a new twist when the number is fully spelled out. This can be easily accomplished thanks to the ICU4J library from IBM.
To parse a spelled out number:
//Get a RuleBasedNumberFormat appropriate for French spellout
RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ULocale.ENGLISH,RuleBasedNumberFormat.SPELLOUT);
//The String to parse
String number = "three hundred and forty-five";
//We need to handle the potential ParseException
try
{
//Parse the number
System.out.println(rbnf.parse(number));
}
catch (ParseException e)
{
e.printStackTrace();
}
The output:
345
The same thing for a French Locale:
RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ULocale.FRENCH,RuleBasedNumberFormat.SPELLOUT);
String number = "trois cents quarante-cinq";
try
{
System.out.println(rbnf.parse(number));
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
You want to spell out a localized number like "thirty-six."
ICU4J provides some number formatting capabilities that core Java does not. One of those features is the ability to spell out a numeric value.
This uses the RuleBasedNumberFormat class to convert a numeric value to a spelled out value. In other words "75" can be converted to "seventy-five." This can also be combined with MessageFormat.
To spell out a numeric value:
//Get a RuleBasedNumberFormat appropriate for French spellout
RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ULocale.FRENCH,RuleBasedNumberFormat.SPELLOUT);
//Call format passing in the numeric value to be formatted
System.out.println(rbnf.format(345));
The output:
trois cents quarante-cinq
You want to use a currency other than the default for the region.
We can specify a currency separate from a region. This will give us a numeric format that is appropriate to the locale, but use a currency code for the specified locale.
//Get a locale.
Locale italian = new Locale("it","IT");
//Get a currency instance
Currency c = Currency.getInstance("JPY");
//Get a currency instance
NumberFormat nf = NumberFormat.getCurrencyInstance(italian);
nf.setCurrency(c);
//format and output. Notice the rounding is not limited to two place on the output. Rounding
//is now governed by the locale. Also notice we now use the ISO code istead of a symbol
String f = nf.format(123456.789);
System.out.println(f);
//Parse the value. We must handle the potential ParseException
//Notice that we can not handle the '¥' mark in the parse
try {
System.out.println(nf.parse("JPY 123.456,79"));
} catch (ParseException e) {
e.printStackTrace();
}
The output:
JPY 123.456,79
123456.79