รูปแบบ Java Currency Number


91

มีวิธีจัดรูปแบบทศนิยมดังนี้:

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

ถ้าเป็นตัวเลขกลมๆให้เว้นส่วนทศนิยม มิฉะนั้นจะจัดรูปแบบด้วยทศนิยมสองตำแหน่ง

คำตอบ:


48

ฉันสงสัยมัน. ปัญหาคือ 100 จะไม่ 100 ถ้ามันเป็นโฟลตปกติ 99.9999999999 หรือ 100.0000001 หรืออะไรทำนองนั้น

หากคุณต้องการจัดรูปแบบด้วยวิธีนี้คุณต้องกำหนด epsilon นั่นคือระยะห่างสูงสุดจากจำนวนเต็มและใช้การจัดรูปแบบจำนวนเต็มหากความแตกต่างมีค่าน้อยกว่าและเป็นทศนิยมอย่างอื่น

สิ่งนี้จะทำเคล็ดลับ:

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 รอง: การลอยสามารถเป็น 100 ได้อย่างแน่นอนโดยมีรูปแบบบิต 0x42c80000
Karol S

2
ใช่ตามที่ Karol S ระบุไว้ตัวเลขจำนวนมากสามารถจับคู่ได้ทุกประการโดยการลอย ไม่ใช่ตัวเลขทั้งหมด 100 เป็นตัวเลขหนึ่งตัวที่สามารถแทนค่าได้คุณควรพิจารณาตัวเลขที่ไม่สามารถเป็นตัวแทนได้
csga5000

160

ฉันขอแนะนำให้ใช้แพ็คเกจ java.text:

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

สิ่งนี้มีประโยชน์เพิ่มเติมในการระบุตำแหน่งที่ตั้ง

แต่ถ้าคุณต้องการให้ตัดสตริงที่คุณได้รับกลับมาหากเป็นเงินทั้งดอลลาร์:

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

17
คุณไม่ควรใช้คู่เพื่อแสดงสกุลเงิน แปลงเป็น longs และจัดการจุดทศนิยมด้วยตัวคุณเองหรือใช้BigDecimalกับฟอร์แมตเตอร์ joda-money.sourceforge.netควรเป็นไลบรารีที่ดีที่จะใช้เมื่อเสร็จสิ้น
gpampara

5
ฉันเห็นด้วย re: double! = money แต่นั่นไม่ใช่วิธีการตั้งคำถาม
duffymo

3
คุณหมายความว่าอย่างไรที่สกุลเงินทำงาน? ฉันสามารถพูดได้ว่ามีค่าใช้จ่าย $ 1 ไม่ใช่ $ 1.00 .... มีวิธีการแสดงสกุลเงินที่แตกต่างกัน (นอกเหนือจากค่าเริ่มต้น) และคำถามนี้จะถามว่าจะละเว้นส่วนทศนิยมได้อย่างไรหากเป็นจำนวนเต็ม
DD.

1
มันเป็นปัญหาในการแสดงผล ใส่ตรรกะใน UI ของคุณเพื่อยอมรับสกุลเงินเป็นสตริงและตัดทอนทศนิยมและเซ็นต์หากเป็นดอลลาร์ที่แน่นอน
duffymo

2
เห็นด้วย - นั่นคือเหตุผลที่ฉันแนะนำให้ใช้ Locale เมื่อฉันเขียนเมื่อ 5.5 ปีที่แล้ว "แต่ถ้าคุณต้อง .... " เป็นวลีสำคัญ
duffymo

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

หรือ

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

วิธีที่ดีที่สุดในการแสดงสกุลเงิน

เอาต์พุต

$ 200.00

หากคุณไม่ต้องการใช้เครื่องหมายให้ใช้วิธีนี้

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

200.00 น

นอกจากนี้ยังสามารถใช้ (ด้วยตัวคั่นหลักพัน)

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

2,000,000.00


ดูเหมือนว่าจะไม่มีการอ้างอิงหรือใช้ "สกุลเงิน" หลังจากประกาศ ... มีผลข้างเคียงของบรรทัดที่ 3 หรือไม่? หรือเหตุผลบางอย่างที่คุณรวมไว้?
Damian

อ่านเพิ่มเติมเกี่ยวกับ [Class Locale] [1] [1]: docs.oracle.com/javase/7/docs/api/java/util/…
Thilina Dharmasena

18

ฉันไม่พบวิธีแก้ปัญหาที่ดีหลังจากค้นหาด้วย Google เพียงโพสต์วิธีแก้ปัญหาของฉันเพื่อให้ผู้อื่นอ้างอิง ใช้priceToStringเพื่อจัดรูปแบบเงิน

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

เขาไม่เคยพูดว่ามันดีกว่า เขาเพิ่งโพสต์วิธีแก้ปัญหาของเขาเพื่อให้คนอื่นสามารถอ้างอิงได้ อย่างน้อยที่สุดที่คุณสามารถพูดได้คือขอบคุณ
Umang Desai

1
จะเกิดอะไรขึ้นถ้าฉันต้องการแสดงราคาในรูปแบบอินเดีย ไม่มีทศนิยม รูปแบบ -> ##, ##, ###
Bhuvan

ที่เมธอด priceWithDecimal (Double) ลองเปลี่ยนมาสก์"###,###,###.00"เพื่อ"###,###,##0.00"แสดง "0,00" เมื่อค่าเป็น "0"
dellasavia

1
ในทางกลับกันจะแปลงสกุลเงินที่จัดรูปแบบเป็น Double อีกครั้ง
Vivek Shankar

6

ใช่. คุณสามารถใช้ได้ java.util.formatter คุณสามารถใช้สตริงการจัดรูปแบบเช่น "% 10.2f"


String.format()เป็นกระดาษห่อหุ้มแบบคงที่ที่ดีสำหรับสิ่งนั้น ไม่แน่ใจว่าทำไมคุณถึงใช้ '10'
Xr.

เนื่องจากไม่มีคำแนะนำเกี่ยวกับขนาดของตัวเลขฉันจึงเลือก 10 Ex Recto เราไม่รู้ว่านี่คือราคาขนมแท่งหรือค่ารถ ฉันเชื่อว่าคุณสามารถทำ "% .2f" ได้เช่นกันเพื่อไม่ให้ขนาดรวมไม่ถูกผูกไว้
dj_segfault

DD ต้องการให้ส่วนทศนิยมถูกละไว้หากจำนวนนั้นเป็นจำนวนหน่วยสกุลเงินรอบ
jarnbjo

6

ฉันใช้อันนี้ (ใช้ StringUtils จาก commons-lang):

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

คุณต้องดูแลเฉพาะสถานที่และสตริงที่เกี่ยวข้องที่จะสับเท่านั้น


5

ฉันคิดว่านี่เป็นเรื่องง่ายและชัดเจนสำหรับการพิมพ์สกุลเงิน:

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

ผลผลิต: $ 12,345.68

และหนึ่งในทางออกที่เป็นไปได้สำหรับคำถาม:

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

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

เอาท์พุต:

100

100.10


คุณพลาดประเด็นของโพสต์ ถ้าจำนวนนั้นเป็นจำนวนเต็มฉันไม่ต้องการให้แสดงทศนิยม
DD.

DD. ฉันขอโทษและฉันได้แก้ไขคำตอบตามคำถามแล้ว
Andrew

5

โดยปกติเราจะต้องทำการผกผันหากฟิลด์เงิน json ของคุณเป็นแบบโฟลตอาจเป็น 3.1, 3.15 หรือเพียงแค่ 3

ในกรณีนี้คุณอาจต้องปัดเศษเพื่อการแสดงผลที่เหมาะสม (และเพื่อให้สามารถใช้มาสก์บนช่องป้อนข้อมูลได้ในภายหลัง):

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

วิธีที่ดีที่สุดในการทำเช่นนั้น

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

เอาต์พุต:

$123.50

หากคุณต้องการเปลี่ยนสกุลเงิน

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

เอาต์พุต:

123.50

4

คุณควรทำสิ่งนี้:

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

ซึ่งพิมพ์:

100

100,10


Math.round (d)! = d จะใช้ได้ไหม ด้วยการลอยบ่อยๆ! = แม้ว่าคุณจะคิดว่าเป็น
ภายนอก

1
อีกวิธีหนึ่งถ้า d จะเป็น 100.000000000000001 ก็จะยังคงพิมพ์เป็น 100
Stefan De Boey

4

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ ...

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
วิธีนี้ใช้ไม่ได้ผล 100.1 -> "100.1" ตัวอย่างเช่นดูstackoverflow.com/questions/5033404/…
davnicwil


4

ฉันเห็นด้วยกับ @duffymo ว่าคุณต้องใช้java.text.NumberFormatวิธีการนี้ คุณสามารถจัดรูปแบบทั้งหมดได้โดยไม่ต้องใช้ String ใด ๆ เปรียบเทียบตัวเอง:

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

สองบิตที่จะชี้ให้เห็น:

  • ทั้งหมดนี้ Math.round(priceAsDouble * 100) % 100เป็นเพียงการแก้ไขความไม่ถูกต้องของคู่ผสม / โฟลต โดยพื้นฐานแล้วเพียงแค่ตรวจสอบว่าเราปัดไปที่ตำแหน่งหลักร้อย (อาจเป็นอคติของสหรัฐฯ) มีเซนต์เหลืออยู่หรือไม่
  • เคล็ดลับในการลบทศนิยมคือsetMaximumFractionDigits()วิธีการ

ไม่ว่าตรรกะของคุณจะเป็นอย่างไรในการพิจารณาว่าทศนิยมควรถูกตัดทอนหรือsetMaximumFractionDigits()ไม่ควรใช้


1
เรื่องจุดของคุณเกี่ยวกับ*100และ%100ถูกสหรัฐลำเอียงคุณสามารถใช้Math.pow(10, formatter.getMaximumFractionDigits())แทนการกำหนดค่าตายตัว100ที่จะใช้หมายเลขที่ถูกต้องสำหรับสถานที่เกิดเหตุ ...
daiscog

3

หากคุณต้องการทำงานเกี่ยวกับสกุลเงินคุณต้องใช้คลาส BigDecimal ปัญหาคือไม่มีวิธีการจัดเก็บตัวเลขลอยในหน่วยความจำ (เช่นคุณสามารถจัดเก็บ 5.3456 แต่ไม่ใช่ 5.3455) ซึ่งอาจส่งผลต่อการคำนวณที่ไม่ดี

มีบทความดีๆเกี่ยวกับการร่วมมือกับ BigDecimal และสกุลเงิน:

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


2
นี่ไม่เกี่ยวข้องกับคำถามที่ฉันถามเลย
DD.

3

รูปแบบตั้งแต่ 1000000.2 ถึง 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

โพสต์นี้ช่วยให้ฉันได้รับสิ่งที่ต้องการในที่สุด ดังนั้นฉันแค่อยากจะร่วมสนับสนุนรหัสของฉันที่นี่เพื่อช่วยเหลือผู้อื่น นี่คือรหัสของฉันพร้อมคำอธิบาย

รหัสต่อไปนี้:

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

จะกลับมา:

5,-
€ 5,50

jeroensFormat () วิธีการจริง:

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

วิธี displayJeroensFormat ที่เรียกเมธอด 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
    }

จะมีผลลัพธ์ดังนี้

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

รหัสนี้ใช้สกุลเงินปัจจุบันของคุณ ในกรณีของฉันคือฮอลแลนด์ดังนั้นสตริงที่จัดรูปแบบสำหรับฉันจะแตกต่างจากคนในสหรัฐอเมริกา

  • ฮอลแลนด์: 999.999,99
  • สหรัฐอเมริกา: 999,999.99

เพียงแค่ดูอักขระ 3 ตัวสุดท้ายของตัวเลขเหล่านั้น รหัสของฉันมีคำสั่ง if เพื่อตรวจสอบว่าอักขระ 3 ตัวสุดท้ายเท่ากับ ", 00" หรือไม่ หากต้องการใช้สิ่งนี้ในสหรัฐอเมริกาคุณอาจต้องเปลี่ยนเป็น ".00" หากยังไม่ได้ผล


2

ฉันบ้าพอที่จะเขียนฟังก์ชันของตัวเอง:

สิ่งนี้จะแปลงจำนวนเต็มเป็นรูปแบบสกุลเงิน (สามารถแก้ไขทศนิยมได้เช่นกัน):

 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

สำหรับผู้ที่ต้องการจัดรูปแบบสกุลเงิน แต่ไม่ต้องการให้ขึ้นอยู่กับสกุลเงินท้องถิ่นเราสามารถทำได้:

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...

1

นี่คือสิ่งที่ฉันทำโดยใช้จำนวนเต็มแทนจำนวนเงินเป็นเซ็นต์แทน:

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

ปัญหาเกี่ยวกับ NumberFormat.getCurrencyInstance()คือบางครั้งคุณต้องการให้ $ 20 เป็น $ 20 มันดูดีกว่า $ 20.00

หากใครพบวิธีที่ดีกว่านี้โดยใช้ NumberFormat ฉันก็หูผึ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.