Как изменить десятичный разделитель DecimalFormat с запятой на точку / точку?

204

У меня есть этот маленький сумасшедший метод, который преобразует значения BigDecimal в красивые и удобочитаемые строки.

private String formatBigDecimal(BigDecimal bd){
    DecimalFormat df = new DecimalFormat();
    df.setMinimumFractionDigits(3);
    df.setMaximumFractionDigits(3);
    df.setMinimumIntegerDigits(1);
    df.setMaximumIntegerDigits(3);
    df.setGroupingSize(20);
    return df.format(bd);
}

Тем не менее, он также создает так называемый группирующий разделитель, ","который выводит все мои значения следующим образом:

xxx,xxx

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

Я прочитал это и, в частности, это до смерти сейчас, но я не могу найти способ сделать это. Я подхожу к этому неправильно? Есть ли более элегантный способ сделать это? Может быть, даже решение, которое учитывает различные представления локальных номеров, поскольку запятая будет идеальной по европейским стандартам.

MiraFayless
источник
См. Также stackoverflow.com/questions/5236056/…
Вадим

Ответы:

323

Вы можете изменить разделитель либо установив локаль, либо используя DecimalFormatSymbols .

Если вы хотите, чтобы разделитель группировки был точкой, вы можете использовать европейский язык:

NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;

В качестве альтернативы вы можете использовать класс DecimalFormatSymbols для изменения символов, которые появляются в отформатированных числах, созданных методом format. Эти символы включают в себя десятичный разделитель, разделитель группировки, знак минус и знак процента, среди прочего:

DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.'); 
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);

currentLocale можно получить из Locale.getDefault (), то есть:

Locale currentLocale = Locale.getDefault();
Крис
источник
1
Вы можете использовать applyPattern в десятичном формате, чтобы получить свой .00
krystan honor
Я изменил otherSymbols.setDecimalSeparator (','); as otherSymbols.setDecimalSeparator ('.'); Спасибо. Это работает для меня.
Ааканкша
2
так выглядит формат, например, String formatString = "#,###,###,##0.00";см. docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html для синтаксиса
Vulpo
1
«Вы можете использовать европейский язык». Ну, вы не можете использовать какую-либо локаль из Европы, потому Locale.UKчто вернется, 1,567.90 а не 1.567,90
Junior Mayhé
Примечание: NumberFormat.getNumberInstance()может работать необычно медленно на некоторых устройствах Android 7. Альтернатива, String.format()которая работает быстро. См. Stackoverflow.com/questions/2379221/java-currency-number-format
Mr-IDE
14

Европа довольно огромна. Я не уверен, что они используют один и тот же формат. Однако тот или иной ответ поможет.

String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();

NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);

Т.е. используйте правильную локаль.

Reno
источник
1
Действительно, сэр! В Великобритании ожидается «1 234,00 фунтов стерлингов», а во Франции ожидается «1 234,00 €» (разделитель группы, десятичный разделитель, символ валюты и позиция валюты изменились).
Вульпо
9
public String getGermanCurrencyFormat(double value) {
    NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
    nf.setGroupingUsed(true);
    return "€ " + nf.format(value);
}
Имран Хан
источник
5

BigDecimal не соответствует настройкам Locale.

Locale.getDefault(); //returns sl_SI

Словенский язык должен иметь десятичную запятую. Думаю, у меня были странные заблуждения относительно чисел.

a = new BigDecimal("1,2") //throws exception
a = new BigDecimal("1.2") //is ok

a.toPlainString() // returns "1.2" always

Я отредактировал часть моего сообщения, которое не имело смысла, так как оно оказалось из-за человеческой ошибки (забыл зафиксировать данные и искал не ту вещь).

То же самое, что BigDecimal, можно сказать для любых функций Java .toString (). Я думаю, это хорошо в некоторых отношениях. Сериализация например или отладка. Существует уникальное строковое представление.

Также как и другие, упомянутые с помощью форматеров работает нормально. Просто используйте форматтеры, то же самое для внешнего интерфейса JSF, форматеры делают работу правильно и знают язык.

Neikius
источник