Jak zmienić separator dziesiętny DecimalFormat z przecinka na kropkę / punkt?

204

Mam tę małą zwariowaną metodę, która konwertuje wartości BigDecimal na ładne i czytelne ciągi znaków.

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);
}

Jednak generuje również tak zwany separator grupowania, ","który sprawia, że ​​wszystkie moje wartości wyglądają następująco:

xxx,xxx

Potrzebuję separatora, który będzie kropką lub kropką, a nie przecinkiem. Czy ktoś ma jakiś pomysł, jak dokonać tego małego wyczynu?

Przeczytałem to, a zwłaszcza to na śmierć, ale nie mogę znaleźć sposobu, aby to zrobić. Czy podchodzę do tego niewłaściwie? Czy istnieje o wiele bardziej elegancki sposób na zrobienie tego? Może nawet rozwiązanie uwzględniające różne lokalne reprezentacje liczb, ponieważ przecinek byłby idealny według standardów europejskich.

MiraFayless
źródło

Odpowiedzi:

323

Możesz zmienić separator, ustawiając ustawienia regionalne lub używając DecimalFormatSymbols .

Jeśli chcesz, aby separator grupowania był punktem, możesz użyć europejskich ustawień regionalnych:

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

Alternatywnie można użyć klasy DecimalFormatSymbols do zmiany symboli pojawiających się w sformatowanych liczbach utworzonych metodą formatowania. Te symbole obejmują między innymi separator dziesiętny, separator grupowania, znak minus i znak procentu:

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

currentLocale można uzyskać z Locale.getDefault () tj .:

Locale currentLocale = Locale.getDefault();
Chris
źródło
1
możesz użyć opcji ApplyPattern w formacie dziesiętnym, aby otrzymać
0,00
Zmieniłem otherSymbols.setDecimalSeparator (','); as otherSymbols.setDecimalSeparator ('.'); Dzięki. To dla mnie działa.
Aakanksha
2
tak wygląda format, np. String formatString = "#,###,###,##0.00";patrz docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html w celu uzyskania składni
Vulpo
1
„Możesz użyć europejskiej wersji językowej”. Cóż, nie możesz używać żadnych ustawień regionalnych z Europy, ponieważ Locale.UKwróci, 1,567.90 a nie 1.567,90
Junior
Uwaga dodatkowa: NumberFormat.getNumberInstance()może działać niezwykle wolno na niektórych urządzeniach z Androidem 7. Alternatywą jest String.format()szybkie działanie. Zobacz stackoverflow.com/questions/2379221/java-currency-number-format
Mr-IDE
14

Europa jest dość ogromna. Nie jestem pewien, czy używają tego samego formatu. Jednak ta lub ta odpowiedź będzie pomocna.

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);

To znaczy użyj poprawnych ustawień regionalnych.

Reno
źródło
1
Rzeczywiście proszę pana! W Wielkiej Brytanii można zobaczyć „1 234,00 £”, zaś we Francji „1 234,00 €” (separator grupy, separator dziesiętny, symbol waluty i pozycja walutowa uległy zmianie).
Vulpo,
9
public String getGermanCurrencyFormat(double value) {
    NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
    nf.setGroupingUsed(true);
    return "€ " + nf.format(value);
}
Imran Khan
źródło
5

BigDecimal wydaje się nie respektować ustawień regionalnych.

Locale.getDefault(); //returns sl_SI

Ustawienia słoweńskie powinny mieć przecinek dziesiętny. Chyba miałem dziwne nieporozumienia dotyczące liczb.

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

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

Zredagowałem część mojego komunikatu, który nie miał sensu, ponieważ okazał się być wynikiem błędu ludzkiego (zapomniałem zatwierdzić dane i patrzyłem na niewłaściwą rzecz).

To samo, co BigDecimal, można powiedzieć o dowolnej funkcji Java .toString (). Myślę, że pod pewnymi względami jest to dobre. Na przykład serializacja lub debugowanie. Istnieje unikalna reprezentacja ciągu.

Podobnie jak inne wspomniane przy użyciu formatowania działa OK. Wystarczy użyć formatererów, takich samych dla frontendu JSF, formaterery wykonują zadanie poprawnie i są świadomi ustawień regionalnych.

Neikius
źródło