Định dạng số tiền tệ Java


89

Có cách nào để định dạng số thập phân như sau:

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

Nếu là số tròn chục thì bỏ phần thập phân. Nếu không, hãy định dạng với hai chữ số thập phân.

Câu trả lời:


48

Tôi nghi ngờ điều đó. Vấn đề là 100 không bao giờ là 100 nếu nó là một float, nó thường là 99.9999999999 hoặc 100.0000001 hoặc tương tự như vậy.

Nếu bạn muốn định dạng nó theo cách đó, bạn phải xác định một epsilon, nghĩa là, một khoảng cách tối đa từ một số nguyên và sử dụng định dạng số nguyên nếu sự khác biệt nhỏ hơn và một số float nếu không.

Một cái gì đó như thế này sẽ thực hiện thủ thuật:

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
Nitpick nhỏ: float có thể chính xác là 100, với mẫu bit 0x42c80000.
Karol S

2
Đúng, như Karol S đã nêu, nhiều số CÓ THỂ được đối sánh chính xác với các phao. Chỉ không phải TẤT CẢ các số. 100 là một số có thể được biểu diễn, bạn chỉ nên tính đến những số không thể.
csga5000

160

Tôi khuyên bạn nên sử dụng gói java.text:

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

Điều này có thêm lợi ích là địa phương cụ thể.

Tuy nhiên, nếu bạn phải, hãy cắt ngắn Chuỗi bạn nhận lại nếu đó là toàn bộ đô la:

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

17
Bạn không bao giờ nên sử dụng một số kép để đại diện cho tiền tệ. Chuyển đổi thành longs và tự quản lý dấu thập phân hoặc sử dụng BigDecimalvới một định dạng. joda-money.sourceforge.net phải là một thư viện tốt để sử dụng sau khi hoàn tất.
gpampara

5
Tôi đồng ý re: double! = Money, nhưng đó không phải là cách câu hỏi được đặt ra.
duffymo

3
Ý bạn là gì, đó là cách tiền tệ hoạt động? Tôi có thể nói một cái gì đó có giá 1 đô la chứ không phải 1 đô la .... có nhiều cách khác nhau để hiển thị tiền tệ (khác với mặc định) và câu hỏi này yêu cầu làm thế nào để bỏ qua phần thập phân nếu nó là một số nguyên.
ĐĐ.

1
Đó là một vấn đề kết xuất. Đặt logic trong giao diện người dùng của bạn để chấp nhận đơn vị tiền tệ dưới dạng Chuỗi và cắt bớt phần thập phân và xu nếu đó là một đô la chính xác.
duffymo 10/12/12

2
Đồng ý - đó là lý do tại sao tôi khuyên bạn nên sử dụng Locale khi viết bài này cách đây 5,5 năm. "Nhưng, nếu bạn phải, ...." là cụm từ chính.
duffymo 14/09/15

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

hoặc là

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

Cách tốt nhất để hiển thị tiền tệ

Đầu ra

$ 200,00

Nếu bạn không muốn sử dụng dấu hiệu, hãy sử dụng phương pháp này

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

200,00

Điều này cũng có thể được sử dụng (Với dấu phân cách nghìn)

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

2.000.000,00


Có vẻ như "tiền tệ" không được tham chiếu hoặc sử dụng sau khi nó được khai báo ... có tác dụng phụ của dòng 3 không? Hoặc một số lý do bạn bao gồm nó?
Damian

Đọc thêm về [ Ngôn ngữ
Thilina Dharmasena

18

Tôi không tìm thấy giải pháp nào tốt sau khi tìm kiếm trên google, chỉ đăng giải pháp của tôi để người khác tham khảo. sử dụng priceToString để định dạng tiền.

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

Anh ấy chưa bao giờ nói nó tốt hơn. NGÀI chỉ đăng giải pháp của mình để những người khác có thể tham khảo từ nó. Ít nhất bạn có thể nói là một lời cảm ơn.
Umang Desai

Điều gì xảy ra nếu tôi muốn hiển thị giá ở định dạng Ấn Độ. Không có số thập phân. Định dạng -> ##, ##, ###
Bhuvan

Tại phương pháp priceWithDecimal (Double), hãy thử thay đổi mặt nạ "###,###,###.00"để "###,###,##0.00"hiển thị "0,00" khi giá trị là "0"
dellasavia

1
gì sẽ ngược lại để chuyển đổi đồng tiền được định dạng để đúp lần nữa
Vivek Shankar

6

Đúng. Bạn có thể sử dụng java.util.formatter . Bạn có thể sử dụng chuỗi định dạng như "% 10.2f"


String.format()là một trình bao bọc tĩnh tốt cho điều đó. Tuy nhiên, không chắc tại sao bạn sử dụng '10'.
Xr.

Không có hướng dẫn về kích thước của số, tôi chọn 10 Ex Recto. Chúng tôi không biết đây là giá của một thanh kẹo hay một chiếc xe hơi. Tôi tin rằng bạn cũng có thể thực hiện "% .2f" để không giới hạn tổng kích thước.
dj_segfault

DD muốn bỏ qua phần thập phân, nếu số tiền là một số tròn đơn vị tiền tệ.
jarnbjo

6

Tôi đang sử dụng cái này (sử dụng StringUtils từ commons-lang):

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

Bạn chỉ phải quan tâm đến miền địa phương và Chuỗi tương ứng để chặt.


5

Tôi nghĩ điều này đơn giản và rõ ràng để in một loại tiền tệ:

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

sản lượng: $ 12.345,68

Và một trong những giải pháp khả thi cho câu hỏi:

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

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

Đầu ra:

100

100,10


Bạn đã bỏ lỡ điểm của bài viết. Nếu số là số nguyên, tôi không muốn hiển thị bất kỳ số thập phân nào.
ĐĐ.

ĐĐ. Tôi xin lỗi, và tôi đã sửa câu trả lời theo câu hỏi.
Andrew

5

Chúng tôi thường sẽ cần làm ngược lại, nếu trường tiền json của bạn là một phao, nó có thể có dạng 3,1, 3,15 hoặc chỉ 3.

Trong trường hợp này, bạn có thể cần phải làm tròn nó để hiển thị thích hợp (và để có thể sử dụng mặt nạ trên trường nhập liệu sau này):

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

cách tốt nhất để làm điều đó.

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

đầu ra:

$123.50

Nếu bạn muốn thay đổi tiền tệ,

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

đầu ra:

123.50

4

bạn nên làm điều gì đó như sau:

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

mà in:

100

100,10


Math.round (d)! = D có hoạt động không? Với float it thường xuyên! = Ngay cả khi bạn nghĩ là như vậy.
extraneon

1
theo cách khác, nếu d sẽ là 100.000000000000001 thì nó vẫn được in là 100
Stefan De Boey

4

Tôi biết đây là một câu hỏi cũ nhưng ...

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
Điều này không hoạt động, chẳng hạn như 100,1 -> "100,1" - xem stackoverflow.com/questions/5033404/…
davnicwil,

4

Bạn chỉ có thể làm điều gì đó như thế này và chuyển toàn bộ số và sau đó là xu.

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

4

Tôi đồng ý với @duffymo rằng bạn cần sử dụng các java.text.NumberFormatphương pháp cho những việc này. Bạn thực sự có thể thực hiện tất cả các định dạng nguyên bản trong đó mà không cần thực hiện bất kỳ Chuỗi nào so sánh với chính bạn:

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

Vài điều cần chỉ ra:

  • Toàn bộ Math.round(priceAsDouble * 100) % 100 chỉ là làm việc xung quanh sự thiếu chính xác của đôi / số nổi. Về cơ bản, chỉ cần kiểm tra xem chúng ta làm tròn đến hàng trăm (có thể đây là sự thiên vị của Hoa Kỳ) là có còn xu hay không.
  • Mẹo để loại bỏ các số thập phân là setMaximumFractionDigits()phương pháp

Bất kể logic của bạn để xác định xem các số thập phân có nên bị cắt ngắn hay không, setMaximumFractionDigits()thì cũng nên được sử dụng.


1
Re quan điểm của bạn về *100%100bị Mỹ-thiên vị, bạn có thể sử dụng Math.pow(10, formatter.getMaximumFractionDigits())thay vì một mã hóa cứng 100để sử dụng số lượng chính xác cho các địa phương ...
daiscog

3

Nếu bạn muốn làm việc với tiền tệ, bạn phải sử dụng lớp BigDecimal. Vấn đề là không có cách nào để lưu trữ một số số thực trong bộ nhớ (ví dụ: bạn có thể lưu trữ 5.3456, nhưng không phải 5.3455), điều này có thể ảnh hưởng đến các phép tính sai.

Có một bài viết hay về cách hợp tác với BigDecimal và tiền tệ:

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


2
Điều này hoàn toàn không liên quan đến câu hỏi tôi đã đặt ra.
ĐĐ.

3

Định dạng từ 1000000.2 đến 1 000 000,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

Bài đăng này thực sự đã giúp tôi cuối cùng đạt được những gì tôi muốn. Vì vậy, tôi chỉ muốn đóng góp mã của mình ở đây để giúp đỡ những người khác. Đây là mã của tôi với một số giải thích.

Đoạn mã sau:

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

Sẽ trở lại:

5,-
€ 5,50

Phương thức jeroensFormat () thực tế:

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

Phương thức displayJeroensFormat gọi phương thức 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
    }

Sẽ có kết quả sau:

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

Mã này sử dụng đơn vị tiền tệ hiện tại của bạn. Trong trường hợp của tôi, đó là Hà Lan nên chuỗi được định dạng đối với tôi sẽ khác so với đối với người ở Mỹ.

  • Hà Lan: 999,999.99
  • US: 999,999,99

Chỉ cần xem 3 ký tự cuối cùng của các số đó. Mã của tôi có câu lệnh if để kiểm tra xem 3 ký tự cuối có bằng ", 00" hay không. Để sử dụng điều này ở Hoa Kỳ, bạn có thể phải thay đổi thành ".00" nếu nó chưa hoạt động.


2

Tôi đã đủ điên để viết hàm của riêng mình:

Điều này sẽ chuyển đổi số nguyên sang định dạng tiền tệ (cũng có thể được sửa đổi cho số thập phân):

 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

Đây là những gì tôi đã làm, sử dụng một số nguyên để biểu thị số tiền dưới dạng xu thay vì:

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

Vấn đề NumberFormat.getCurrencyInstance()là đôi khi bạn thực sự muốn 20 đô la thành 20 đô la, nó chỉ trông đẹp hơn 20 đô la.

Nếu ai đó tìm ra cách tốt hơn để làm điều này, bằng cách sử dụng NumberFormat, tôi đều thích thú.


1

Đối với những người muốn định dạng đơn vị tiền tệ, nhưng không muốn nó dựa trên địa phương, chúng tôi có thể làm như sau:

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...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.