Formato Java Currency Number


89

C'è un modo per formattare un decimale come segue:

100   -> "100"  
100.1 -> "100.10"

Se è un numero tondo, ometti la parte decimale. Altrimenti formatta con due cifre decimali.

Risposte:


48

Ne dubito. Il problema è che 100 non è mai 100 se è un float, normalmente è 99.9999999999 o 100.0000001 o qualcosa del genere.

Se vuoi formattarlo in questo modo, devi definire un epsilon, cioè una distanza massima da un numero intero, e usare la formattazione intero se la differenza è minore e un float altrimenti.

Qualcosa del genere farebbe il trucco:

public String formatDecimal(float number) {
  float epsilon = 0.004f; // 4 tenths of a cent
  if (Math.abs(Math.round(number) - number) < epsilon) {
     return String.format("%10.0f", number); // sdb
  } else {
     return String.format("%10.2f", number); // dj_segfault
  }
}

8
Minor nitpick: un float può essere esattamente 100, con pattern di bit 0x42c80000.
Karol S

2
Sì, come affermato da Karol S, molti numeri POSSONO essere esattamente abbinati a galleggianti. Solo non TUTTI i numeri. 100 è un numero che può essere rappresentato, dovresti solo tenere conto dei numeri che non possono essere.
csga5000

160

Consiglierei di utilizzare il pacchetto java.text:

double money = 100.1;
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String moneyString = formatter.format(money);
System.out.println(moneyString);

Questo ha l'ulteriore vantaggio di essere specifico per le impostazioni locali.

Ma, se devi, troncare la stringa che ottieni se è un dollaro intero:

if (moneyString.endsWith(".00")) {
    int centsIndex = moneyString.lastIndexOf(".00");
    if (centsIndex != -1) {
        moneyString = moneyString.substring(1, centsIndex);
    }
}

17
Non dovresti mai usare un doppio per rappresentare le valute. Converti in long e gestisci tu stesso il punto decimale o usalo BigDecimalcon un formattatore. joda-money.sourceforge.net dovrebbe essere una bella libreria da usare una volta terminata .
gpampara

5
Sono d'accordo re: double! = Money, ma non è così che è stata posta la domanda.
duffymo

3
Cosa intendi per come funzionano le valute? Posso dire che qualcosa costa $ 1 non $ 1,00 .... ci sono modi diversi di visualizzare le valute (oltre a quello predefinito) e questa domanda chiede come omettere la parte decimale se è un numero intero.
DD.

1
È un problema di rendering. Inserisci la logica nella tua interfaccia utente per accettare la valuta come stringa e troncare il decimale e i centesimi se si tratta di un dollaro esatto.
duffymo

2
D'accordo: ecco perché ho consigliato di usare Locale quando l'ho scritto 5,5 anni fa. "Ma, se devi, ...." è la frase chiave.
duffymo

124
double amount =200.0;
Locale locale = new Locale("en", "US");      
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);
System.out.println(currencyFormatter.format(amount));

o

double amount =200.0;
System.out.println(NumberFormat.getCurrencyInstance(new Locale("en", "US"))
        .format(amount));

Il modo migliore per visualizzare la valuta

Produzione

$ 200,00

Se non vuoi usare il segno usa questo metodo

double amount = 200;
DecimalFormat twoPlaces = new DecimalFormat("0.00");
System.out.println(twoPlaces.format(amount));

200.00

Anche questo può essere utilizzato (con il separatore delle migliaia)

double amount = 2000000;    
System.out.println(String.format("%,.2f", amount));          

2.000.000,00


Non sembra che la "valuta" sia referenziata o utilizzata dopo che è stata dichiarata ... c'è un effetto collaterale della riga 3? O per qualche motivo l'hai incluso?
Damian

Ulteriori informazioni su [Class Locale] [1] [1]: docs.oracle.com/javase/7/docs/api/java/util/…
Thilina Dharmasena,

18

Non ho trovato nessuna buona soluzione dopo la ricerca su Google, basta pubblicare la mia soluzione per farne riferimento ad altri. utilizzare priceToString per formattare il denaro.

public static String priceWithDecimal (Double price) {
    DecimalFormat formatter = new DecimalFormat("###,###,###.00");
    return formatter.format(price);
}

public static String priceWithoutDecimal (Double price) {
    DecimalFormat formatter = new DecimalFormat("###,###,###.##");
    return formatter.format(price);
}

public static String priceToString(Double price) {
    String toShow = priceWithoutDecimal(price);
    if (toShow.indexOf(".") > 0) {
        return priceWithDecimal(price);
    } else {
        return priceWithoutDecimal(price);
    }
}

Non ha mai detto che fosse migliore. Ha appena pubblicato la sua soluzione in modo che altri possano fare riferimento da essa. Almeno si potrebbe dire è un grazie.
Umang Desai

E se volessi visualizzare il prezzo in formato indiano. Senza decimali. Formato -> ##, ##, ###
Bhuvan

Al metodo priceWithDecimal (Double), prova a cambiare la maschera "###,###,###.00"in "###,###,##0.00"per mostrare "0,00" quando il valore è "0"
dellasavia

1
cosa farà il viceversa per convertire di nuovo la valuta formattata in Double
Vivek Shankar

6

Sì. Puoi usare java.util.formatter . Puoi usare una stringa di formattazione come "% 10.2f"


String.format()è un bel wrapper statico per questo. Non sono sicuro del motivo per cui usi "10", però.
Xr.

Non avendo indicazioni sulla grandezza del numero, ho scelto 10 Ex Recto. Non sappiamo se questo è il prezzo di una barretta di cioccolato o di un'auto. Credo che tu possa anche semplicemente fare "% .2f" per lasciare la dimensione totale illimitata.
dj_segfault

DD voleva che la parte decimale fosse omessa, se l'importo è un numero tondo di unità monetarie.
jarnbjo

6

Sto usando questo (usando StringUtils da commons-lang):

Double qty = 1.01;
String res = String.format(Locale.GERMANY, "%.2f", qty);
String fmt = StringUtils.removeEnd(res, ",00");

Devi solo occuparti del locale e della stringa corrispondente da tagliare.


5

Penso che questo sia semplice e chiaro per stampare una valuta:

DecimalFormat df = new DecimalFormat("$###,###.##"); // or pattern "###,###.##$"
System.out.println(df.format(12345.678));

uscita: $ 12.345,68

E una delle possibili soluzioni per la domanda:

public static void twoDecimalsOrOmit(double d) {
    System.out.println(new DecimalFormat(d%1 == 0 ? "###.##" : "###.00").format(d));
}

twoDecimalsOrOmit((double) 100);
twoDecimalsOrOmit(100.1);

Produzione:

100

100.10


Hai perso il punto del post. Se il numero è un numero intero, non voglio visualizzare i decimali.
DD.

DD. Mi dispiace e ho corretto la risposta in base alla domanda.
Andrew

5

Di solito avremo bisogno di fare l'inverso, se il tuo campo json money è un float, potrebbe arrivare come 3.1, 3.15 o solo 3.

In questo caso potrebbe essere necessario arrotondarlo per una visualizzazione corretta (e per poter utilizzare una maschera su un campo di input in un secondo momento):

floatvalue = 200.0; // it may be 200, 200.3 or 200.37, BigDecimal will take care
Locale locale = new Locale("en", "US");      
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale);

BigDecimal valueAsBD = BigDecimal.valueOf(value);
    valueAsBD.setScale(2, BigDecimal.ROUND_HALF_UP); // add digits to match .00 pattern

System.out.println(currencyFormatter.format(amount));

5

questo modo migliore per farlo.

    public static String formatCurrency(String amount) {
        DecimalFormat formatter = new DecimalFormat("###,###,##0.00");
        return formatter.format(Double.parseDouble(amount));
    }

100 -> "100,00"
100,1 -> "100,10"


5
NumberFormat currency = NumberFormat.getCurrencyInstance();
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);

produzione:

$123.50

Se vuoi cambiare la valuta,

NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CHINA);
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);

produzione:

123.50

4

dovresti fare qualcosa del genere:

public static void main(String[] args) {
    double d1 = 100d;
    double d2 = 100.1d;
    print(d1);
    print(d2);
}

private static void print(double d) {
    String s = null;
    if (Math.round(d) != d) {
        s = String.format("%.2f", d);
    } else {
        s = String.format("%.0f", d);
    }
    System.out.println(s);
}

che stampa:

100

100,10


Math.round (d)! = D funzionerà? Con i float spesso! = Anche se pensi che lo sia.
extraneon

1
viceversa, se d fosse 100.000000000000001 allora sarebbe ancora stampato come 100
Stefan De Boey

4

So che questa è una vecchia domanda ma ...

import java.text.*;

public class FormatCurrency
{
    public static void main(String[] args)
    {
        double price = 123.4567;
        DecimalFormat df = new DecimalFormat("#.##");
        System.out.print(df.format(price));
    }
}

3
Questo non funziona, lo fa 100.1 -> "100.1", per esempio - vedi stackoverflow.com/questions/5033404/...
davnicwil

4

Puoi semplicemente fare qualcosa del genere e passare il numero intero e poi i centesimi dopo.

String.format("$%,d.%02d",wholeNum,change);

4

Sono d'accordo con @duffymo sul fatto che è necessario utilizzare i java.text.NumberFormatmetodi per questo genere di cose. Puoi effettivamente eseguire tutta la formattazione in modo nativo senza eseguire alcun confronto String te stesso:

private String formatPrice(final double priceAsDouble) 
{
    NumberFormat formatter = NumberFormat.getCurrencyInstance();
    if (Math.round(priceAsDouble * 100) % 100 == 0) {
        formatter.setMaximumFractionDigits(0);
    }
    return formatter.format(priceAsDouble);
}

Un paio di bit da sottolineare:

  • Il tutto Math.round(priceAsDouble * 100) % 100sta solo aggirando le imprecisioni di double / float. Fondamentalmente solo controllando se arrotondiamo alle centinaia (forse questo è un pregiudizio degli Stati Uniti) ci sono centesimi rimasti.
  • Il trucco per rimuovere i decimali è il setMaximumFractionDigits()metodo

Qualunque sia la tua logica per determinare se i decimali debbano essere troncati o meno, setMaximumFractionDigits()dovresti usarla.


1
Per quanto riguarda il tuo punto di vista *100ed %100essendo di parte negli Stati Uniti, potresti usare Math.pow(10, formatter.getMaximumFractionDigits())invece di un hard-coded 100per usare il numero corretto per la lingua ...
daiscog

3

Se vuoi lavorare sulle valute, devi usare la classe BigDecimal. Il problema è che non c'è modo di memorizzare alcuni numeri in virgola mobile in memoria (ad es. È possibile memorizzare 5.3456, ma non 5.3455), il che può avere effetti in calcoli errati.

C'è un bell'articolo su come collaborare con BigDecimal e le valute:

http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents.html


2
Questo è completamente irrilevante per la domanda che ho posto.
DD.

3

Formato da 1000000.2 a 1000000,20

private static final DecimalFormat DF = new DecimalFormat();

public static String toCurrency(Double d) {
    if (d == null || "".equals(d) || "NaN".equals(d)) {
        return " - ";
    }
    BigDecimal bd = new BigDecimal(d);
    bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
    DecimalFormatSymbols symbols = DF.getDecimalFormatSymbols();
    symbols.setGroupingSeparator(' ');
    String ret = DF.format(bd) + "";
    if (ret.indexOf(",") == -1) {
        ret += ",00";
    }
    if (ret.split(",")[1].length() != 2) {
        ret += "0";
    }
    return ret;
}

2

Questo post mi ha davvero aiutato a ottenere finalmente quello che voglio. Quindi volevo solo contribuire con il mio codice qui per aiutare gli altri. Ecco il mio codice con alcune spiegazioni.

Il codice seguente:

double moneyWithDecimals = 5.50;
double moneyNoDecimals = 5.00;
System.out.println(jeroensFormat(moneyWithDecimals));
System.out.println(jeroensFormat(moneyNoDecimals));

Tornerà:

5,-
€ 5,50

Il metodo jeroensFormat () effettivo:

public String jeroensFormat(double money)//Wants to receive value of type double
{
        NumberFormat dutchFormat = NumberFormat.getCurrencyInstance();
        money = money;
        String twoDecimals = dutchFormat.format(money); //Format to string
        if(tweeDecimalen.matches(".*[.]...[,]00$")){
            String zeroDecimals = twoDecimals.substring(0, twoDecimals.length() -3);
                return zeroDecimals;
        }
        if(twoDecimals.endsWith(",00")){
            String zeroDecimals = String.format("€ %.0f,-", money);
            return zeroDecimals; //Return with ,00 replaced to ,-
        }
        else{ //If endsWith != ,00 the actual twoDecimals string can be returned
            return twoDecimals;
        }
}

Il metodo displayJeroensFormat che chiama il metodo jeroensFormat ()

    public void displayJeroensFormat()//@parameter double:
    {
        System.out.println(jeroensFormat(10.5)); //Example for two decimals
        System.out.println(jeroensFormat(10.95)); //Example for two decimals
        System.out.println(jeroensFormat(10.00)); //Example for zero decimals
        System.out.println(jeroensFormat(100.000)); //Example for zero decimals
    }

Avrà il seguente output:

10,5010,9510,-
€ 100.000 (In Holland numbers bigger than € 999,- and wit no decimals don't have ,-)

Questo codice utilizza la tua valuta corrente. Nel mio caso quello è l'Olanda, quindi la stringa formattata per me sarà diversa da quella per qualcuno negli Stati Uniti.

  • Olanda: 999.999,99
  • US: 999.999,99

Guarda gli ultimi 3 caratteri di quei numeri. Il mio codice ha un'istruzione if per verificare se gli ultimi 3 caratteri sono uguali a ", 00". Per usarlo negli Stati Uniti potrebbe essere necessario cambiarlo in ".00" se non funziona già.


2

Ero abbastanza pazzo da scrivere la mia funzione:

Questo convertirà il formato intero in valuta (può essere modificato anche per i decimali):

 String getCurrencyFormat(int v){
        String toReturn = "";
        String s =  String.valueOf(v);
        int length = s.length();
        for(int i = length; i >0 ; --i){
            toReturn += s.charAt(i - 1);
            if((i - length - 1) % 3 == 0 && i != 1) toReturn += ',';
        }
        return "$" + new StringBuilder(toReturn).reverse().toString();
    }

2
  public static String formatPrice(double value) {
        DecimalFormat formatter;
        if (value<=99999)
          formatter = new DecimalFormat("###,###,##0.00");
        else
            formatter = new DecimalFormat("#,##,##,###.00");

        return formatter.format(value);
    }

1

Questo è quello che ho fatto, utilizzando un numero intero per rappresentare invece l'importo in centesimi:

public static String format(int moneyInCents) {
    String format;
    Number value;
    if (moneyInCents % 100 == 0) {
        format = "%d";
        value = moneyInCents / 100;
    } else {
        format = "%.2f";
        value = moneyInCents / 100.0;
    }
    return String.format(Locale.US, format, value);
}

Il problema NumberFormat.getCurrencyInstance()è che a volte vuoi davvero $ 20 per $ 20, sembra solo meglio di $ 20,00.

Se qualcuno trova un modo migliore per farlo, usando NumberFormat, sono tutto orecchie.


1

Per le persone che vogliono formattare la valuta, ma non vogliono che sia basata su locale, possiamo farlo:

val numberFormat = NumberFormat.getCurrencyInstance() // Default local currency
val currency = Currency.getInstance("USD")            // This make the format not locale specific 
numberFormat.setCurrency(currency)

...use the formator as you want...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.