Java货币编号格式


89

有没有一种格式可以如下设置小数:

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

如果是整数,则省略小数部分。否则,格式要保留两位小数。

Answers:


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
您永远不要使用双精度来代表货币。可以自己转换为long并管理小数点,或者BigDecimal与格式化程序一起使用。 joda-money.sourceforge.net应该是一个不错的库,一旦完成就可以使用。
gpampara

5
我同意:两倍!=金钱,但这不是问题所在。
duffymo 2010年

3
您是什么意思,那就是货币如何运作?我可以说某物的价格是1美元,而不是1.00美元。...显示货币(默认值除外)的方式有所不同,这个问题问如何省略小数部分(如果是整数)。
DD。

1
这是一个渲染问题。将逻辑放在您的UI中,以将货币接受为String并截断十进制和美分(如果它是确切的美元)。
duffymo

2
同意-这就是为什么我在5.5年前撰写此文章时建议使用Locale的原因。“但是,如果必须的话,.....”是关键词。
duffymo 2015年

124
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


声明之后,它看起来不像是在引用或使用“ currency” ...第3行是否有副作用?还是出于某些原因您将其包括在内?
达米安

要进一步了解[类区域设置] [1] [1]:docs.oracle.com/javase/7/docs/api/java/util/...
Thilina达马塞纳

18

谷歌搜索后,我没有找到任何好的解决方案,只是发布我的解决方案以供其他参考。使用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

如果我想以印度格式显示价格怎么办。不带小数。格式-> ##,##,###
Bhuvan 2013年

在priceWithDecimal(Double)方法中,尝试将值更改为“ 0”时将掩码"###,###,###.00"更改"###,###,##0.00"为显示“ 0,00”
dellasavia

1
反之亦然,将格式化后的货币再次转换为Double是什么
Vivek Shankar

6

是。您可以使用java.util.formatter。您可以使用格式字符串,例如“%10.2f”


String.format()是一个很好的静态包装器。不过,不确定为什么要使用“ 10”。
Xr。

由于没有给出有关大小大小的指导,我选择了10 Ex Recto。我们不知道这是糖果还是汽车的价格。我相信您也可以执行“%.2f”以使总大小不受限制。
dj_segfault

DD希望省略小数部分(如果金额为整数货币单位)。
jarnbjo 2010年

6

我正在使用这个(使用commons-lang的StringUtils):

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。很抱歉,我已根据问题更正了答案。
安德鲁

5

我们通常需要做相反的操作,如果您的json money字段是浮点数,则可能为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有效吗?对于浮点数,即使您认为确实如此,也经常!=。
Extraneon 2010年

1
反之,如果d为100.000000000000001,则仍将其打印为100
Stefan De Boey 2010年

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

您可以执行类似的操作,然后传递整数,然后传递美分。

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

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 2015年


3

格式从1000000.2到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

这篇文章确实帮助我终于得到了我想要的。所以我只想在这里贡献我的代码以帮助他人。这是我的代码,并有一些解释。

如下代码:

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

调用方法jeroensFormat()的displayJeroensFormat方法

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

这就是我所做的,使用整数将金额表示为美分:

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的更好方法,我将不知所措。


1

对于想要格式化货币但不希望基于本地货币的人,我们可以这样做:

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...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.