Accounting Currency Formatting – Localization
By Gigi Rosen / January 24, 2021 / No Comments / Conditional Formatting, Oracle Certifications, The ZonedDateTime Class
Accounting Currency Formatting
By default, the minus sign (-) is used as a prefix when formatting negative numbers using a currency formatter returned by the NumberFormat.getCurrencyInstance() method.
NumberFormat df0 = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(df0.format(-9.99)); // -$9.99
However, in accountancy, it is a common practice to enclose a negative currency value in parentheses, (). For example, ($9.99) is interpreted as -$9.99. One way to format negative currency values with parentheses for a given locale is to create the locale so that it allows this style for currency formatting. The code below illustrates how this can be achieved for the US locale.
A US locale is created at (1) below that formats negative currency values with parentheses. The Locale.forLanguageTag() method creates a locale from the specified language tag en-US-u-cf-account that consists of several subtags separated by a hyphen:
- en: Represents the English language
- US: Represents the United States
- u: Indicates that a Unicode locale/language extension is specified as a key–value pair
- cf-account: The key–value pair, where the key cf stands for currency format, and the value account means to use parentheses for negative numbers
The language tag en-US-u-cf-standard will result in a US locale that is the same as Locale.US. For further details, kindly consult the Unicode Locale Data Markup Language (LDML).
The currency formatter created at (2) for the locale created at (1) will now use parentheses for negative currency values.
Locale loc = Locale.forLanguageTag(“en-US-u-cf-account”); // (1)
NumberFormat df = NumberFormat.getCurrencyInstance(loc); // (2)
System.out.println(df.format(-9.99)); // ($9.99)
Parsing Strings to Number, Currency, and Percentage Values
A number formatter can be used to parse strings that contain text representations of numeric values. The abstract class NumberFormat provides the following concrete methods for this purpose.
Number parse(String str) throws ParseException
Parses the text in the specified string from the beginning of the string to produce a Number. No leading whitespace is allowed. Any trailing characters after the parsed text are ignored. This method throws the checked java.text.Parse-Exception if unsuccessful.
void setParseIntegerOnly(boolean intOnly)
boolean isParseIntegerOnly()
Set or get the status if this formatter should only parse integers.
The class DecimalFormat specifically provides the following concrete methods to customize the formatter to parse BigDecimal numbers.
void setParseBigDecimal(boolean newValue)
boolean isParseBigDecimal()
Set or get the status if this formatter should parse BigDecimal numbers.
The code calling the parse() method must be prepared to handle a checked Parse-Exception—for brevity, exception handling is omitted in the code below.
The following code shows the Norwegian number formatter from earlier being used to parse strings. At (1), the result is a long value because the dot (.) in the input string is a delimiter and not a legal character according to the number format used in the Norwegian locale. At (2), the result is a double value because the comma (,) in the input string is the decimal separator in the Norwegian locale. Note that the print statement prints the resulting number according to the default locale (U.S., in this case). For the US locale, the dot (.) and the comma (,) are interpreted as the decimal separator and the group separator, respectively.
System.out.println(nfNOR.parse(“9876.598”)); // (1) 9876
System.out.println(nfNOR.parse(“9876,598”)); // (2) 9876.598
System.out.println(nfUS.parse(“9876.598”)); // (3) 9876.598
System.out.println(nfUs.parse(“9876,598”)); // (4) 9876598
In order to parse a string to a BigDecimal, we can proceed via a DecimalFormat that is customized to parse a BigDecimal. The overloaded parse() method below returns a Number, which is actually a BigDecimal in this case.
DecimalFormat dfUS = (DecimalFormat) nfUS;
dfUS.setParseBigDecimal(true);
BigDecimal bd = (BigDecimal) dfUS.parse(“9876,598”);
The following code demonstrates using a currency formatter as a parser. Note that the currency symbol is interpreted according to the locale in the currency formatter.
In the Norwegian locale, the decimal symbol is not a period (.) when parsing numbers; it is a delimiter in the input string, as can be seen at (1) below. For some locales, a non-breaking space (\u00a0) may be required between the currency symbol and the first digit, as can be seen at (2).
The grouping symbol in the Norwegian locale is not a space, and therefore, it is interpreted as a delimiter, as can be seen at (3). An explicit nbsp can be used for grouping digits, if necessary, in order to parse the input string, as at (4). For the US locale, no such considerations are necessary, as can be seen at (5).
System.out.println(cfNOR.parse(“kr\u00a09876.59”)); // (1) 9876
System.out.println(cfNOR.parse(“kr\u00a09876,59”)); // (2) 9876.59
System.out.println(cfNOR.parse(“kr\u00a09 876,59”)); // (3) 9
System.out.println(cfNOR.parse(“kr\u00a09\u00a0876,59”)); // (4) 9876.59
System.out.println(cfUS.parse(“$9876.59”)); // (5) 9876.59
When parsing percentages, a nbsp might be required between the percentage value and the percent sign (%) in the input string, as can be seen at (1) below for the Norwegian locale. For parsing a percentage value according to the US locale, no such consideration is necessary, as can be seen at (2). However, the format of the percentage value is according to the locale used by the formatter, as can be seen at (1) and (2).
Click here to view code image System.out.println(pfNOR.parse(“15,75\u00a0%”)); // (1) 0.1575
System.out.println(pfUS.parse(“25.5%”)); // (2) 0.255