¿Hay alguna forma de formatear un decimal de la siguiente manera?
100 -> "100"
100.1 -> "100.10"
Si es un número redondo, omita la parte decimal. De lo contrario, formatee con dos lugares decimales.
Respuestas:
Lo dudo. El problema es que 100 nunca es 100 si es un float, normalmente es 99.9999999999 o 100.0000001 o algo así.
Si desea formatearlo de esa manera, debe definir un épsilon, es decir, una distancia máxima de un número entero, y usar formato de entero si la diferencia es menor y un flotante en caso contrario.
Algo como esto haría el truco:
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
}
}
Recomendaría usar el paquete java.text:
double money = 100.1;
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String moneyString = formatter.format(money);
System.out.println(moneyString);
Esto tiene el beneficio adicional de ser específico de la localidad.
Pero, si es necesario, trunca el String que obtienes si es un dólar entero:
if (moneyString.endsWith(".00")) {
int centsIndex = moneyString.lastIndexOf(".00");
if (centsIndex != -1) {
moneyString = moneyString.substring(1, centsIndex);
}
}
BigDecimal
con un formateador. joda-money.sourceforge.net debería ser una buena biblioteca para usar una vez que esté hecho.
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));
La mejor forma de mostrar la moneda
Salida
200,00 $
Si no desea usar el signo, use este método
double amount = 200;
DecimalFormat twoPlaces = new DecimalFormat("0.00");
System.out.println(twoPlaces.format(amount));
200,00
Esto también se puede usar (con el separador de miles)
double amount = 2000000;
System.out.println(String.format("%,.2f", amount));
2,000,000.00
No encontré ninguna buena solución después de la búsqueda en Google, solo publique mi solución para que otros puedan consultarla. use priceToString para formatear dinero.
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);
}
}
"###,###,###.00"
para "###,###,##0.00"
mostrar "0,00" cuando el valor sea "0"
Si. Puede utilizar java.util.formatter . Puede utilizar una cadena de formato como "% 10.2f"
String.format()
es una buena envoltura estática para eso. Sin embargo, no estoy seguro de por qué usa '10'.
Estoy usando este (usando StringUtils de commons-lang):
Double qty = 1.01;
String res = String.format(Locale.GERMANY, "%.2f", qty);
String fmt = StringUtils.removeEnd(res, ",00");
Solo debe cuidar la configuración regional y la Cadena correspondiente para cortar.
Creo que esto es simple y claro para imprimir una moneda:
DecimalFormat df = new DecimalFormat("$###,###.##"); // or pattern "###,###.##$"
System.out.println(df.format(12345.678));
salida: $ 12,345.68
Y una de las posibles soluciones a la pregunta:
public static void twoDecimalsOrOmit(double d) {
System.out.println(new DecimalFormat(d%1 == 0 ? "###.##" : "###.00").format(d));
}
twoDecimalsOrOmit((double) 100);
twoDecimalsOrOmit(100.1);
Salida:
100
100,10
Por lo general, necesitaremos hacer lo inverso, si su campo de dinero json es un flotante, puede ser 3.1, 3.15 o solo 3.
En este caso, es posible que deba redondearlo para una visualización adecuada (y para poder usar una máscara en un campo de entrada más adelante):
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));
esta es la mejor manera de hacer eso.
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"
NumberFormat currency = NumberFormat.getCurrencyInstance();
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);
salida:
$123.50
Si desea cambiar la moneda,
NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.CHINA);
String myCurrency = currency.format(123.5);
System.out.println(myCurrency);
salida:
¥123.50
deberías hacer algo como esto:
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);
}
que imprime:
100
100,10
Sé que esta es una vieja pregunta pero ...
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));
}
}
Puedes hacer algo como esto y pasar el número entero y luego los centavos.
String.format("$%,d.%02d",wholeNum,change);
Estoy de acuerdo con @duffymo en que necesitas usar los java.text.NumberFormat
métodos para este tipo de cosas. De hecho, puede hacer todo el formateo de forma nativa sin hacer ninguna comparación de cadenas:
private String formatPrice(final double priceAsDouble)
{
NumberFormat formatter = NumberFormat.getCurrencyInstance();
if (Math.round(priceAsDouble * 100) % 100 == 0) {
formatter.setMaximumFractionDigits(0);
}
return formatter.format(priceAsDouble);
}
Par de bits para señalar:
Math.round(priceAsDouble * 100) % 100
está trabajando en torno a las inexactitudes de los dobles / flotantes. Básicamente, solo verificando si redondeamos al lugar de las centenas (tal vez esto sea un sesgo de EE. UU.) ¿Quedan centavos? setMaximumFractionDigits()
métodoCualquiera que sea su lógica para determinar si los decimales deben truncarse o no, setMaximumFractionDigits()
debe usarse.
*100
y %100
es empujada por Estados Unidos, se puede utilizar Math.pow(10, formatter.getMaximumFractionDigits())
en lugar de un no modificable 100
de utilizar el número correcto para la configuración regional ...
Si desea trabajar con monedas, debe usar la clase BigDecimal. El problema es que no hay forma de almacenar algunos números flotantes en la memoria (por ejemplo, puede almacenar 5.3456, pero no 5.3455), lo que puede afectar los cálculos incorrectos.
Hay un buen artículo sobre cómo cooperar con BigDecimal y las monedas:
http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents.html
Formato de 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;
}
Esta publicación realmente me ayudó a conseguir finalmente lo que quiero. Así que solo quería contribuir con mi código aquí para ayudar a otros. Aquí está mi código con alguna explicación.
El siguiente código:
double moneyWithDecimals = 5.50;
double moneyNoDecimals = 5.00;
System.out.println(jeroensFormat(moneyWithDecimals));
System.out.println(jeroensFormat(moneyNoDecimals));
Regresará:
€ 5,-
€ 5,50
El método jeroensFormat () real:
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;
}
}
El método displayJeroensFormat que llama al método 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
}
Tendrá la siguiente salida:
€ 10,50
€ 10,95
€ 10,-
€ 100.000 (In Holland numbers bigger than € 999,- and wit no decimals don't have ,-)
Este código usa su moneda actual. En mi caso, eso es Holanda, por lo que la cadena formateada para mí será diferente a la de alguien en los EE. UU.
Solo mira los últimos 3 caracteres de esos números. Mi código tiene una declaración if para verificar si los últimos 3 caracteres son iguales a ", 00". Para usar esto en los EE. UU., Es posible que deba cambiarlo a ".00" si aún no funciona.
Estaba lo suficientemente loco como para escribir mi propia función:
Esto convertirá el formato entero a moneda (también se puede modificar para decimales):
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();
}
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);
}
Esto es lo que hice, usando un número entero para representar la cantidad como centavos en su lugar:
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);
}
El problema NumberFormat.getCurrencyInstance()
es que a veces realmente quieres que $ 20 sean $ 20, simplemente se ve mejor que $ 20,00.
Si alguien encuentra una mejor manera de hacer esto, usando NumberFormat, soy todo oídos.
Para las personas que desean formatear la moneda, pero no quieren que se base en local, podemos hacer esto:
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...