Cómo formatear números en Java
Formatea números en Java con String.format, printf, DecimalFormat y NumberFormat con separadores, decimales y símbolos.
Java ofrece varias formas de convertir un int, double o BigDecimal en una cadena legible para el usuario: separadores de miles, decimales fijos, símbolos de moneda y porcentajes. Este capítulo recorre las herramientas más utilizadas: String.format/printf, DecimalFormat y el NumberFormat consciente de la configuración regional. Para conocer los tipos numéricos que aceptan estos métodos, consulta Java Numbers; para el conjunto completo de conversiones de printf, consulta Java String Formatting.
Formateo rápido con String.format y printf
Para formateo puntual dentro de una línea de registro o System.out, el enfoque de cadena de formato es el camino más corto. printf imprime directamente; String.format devuelve la cadena para que puedas almacenarla.
double price = 1234.5;
System.out.printf("%.2f%n", price); // 1234.50
String s = String.format("%,.2f", price); // 1,234.50
System.out.println(String.format("%08.2f", 42.5)); // 00042.50La conversión %.2f fija dos decimales, la bandera , agrega separadores de agrupación y %08.2f rellena con ceros el campo completo hasta el ancho 8. Usa %n en lugar de \n para un salto de línea correcto según la plataforma. El separador de agrupación sigue la configuración regional predeterminada, por lo que el mismo código puede imprimir 1.234,50 en una máquina alemana.
Patrones personalizados con DecimalFormat
Cuando necesitas control total sobre el patrón, o quieres formatear muchos valores con un objeto reutilizable, usa DecimalFormat. El resultado se describe con un patrón de caracteres # (dígito opcional) y 0 (dígito requerido).
DecimalFormat df = new DecimalFormat("#,##0.00");
df.format(1234.5); // "1,234.50"
df.format(0.5); // "0.50"
DecimalFormat sci = new DecimalFormat("0.###E0");
sci.format(123456); // "1.235E5"DecimalFormat redondea con RoundingMode.HALF_EVEN por defecto, lo que puede sorprenderte (2.5 se redondea a 2). Establece df.setRoundingMode(RoundingMode.HALF_UP) si necesitas el comportamiento cotidiano de "redondear la mitad hacia arriba". Una sola instancia de DecimalFormat no es segura para subprocesos, así que crea una por subproceso o protégela.
Moneda y porcentaje conscientes de la configuración regional
Para moneda y porcentajes, no construyas el patrón manualmente. Los métodos de fábrica de NumberFormat eligen el símbolo correcto, los separadores y el número de dígitos para un Locale.
NumberFormat us = NumberFormat.getCurrencyInstance(Locale.US);
us.format(1234.5); // "$1,234.50"
NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.format(0.87); // "87%"Ten en cuenta que el formateador de porcentaje multiplica por 100, por lo que se pasa 0.87 para obtener 87%. Pasar el Locale correcto es lo que hace que la salida sea adecuada para cada mercado.
| Enfoque | Mejor para | Consciente del locale | Reutilizable |
|---|---|---|---|
printf / String.format | salida puntual | sí (locale predeterminado) | no |
DecimalFormat | patrones personalizados, lotes | sí (configurable) | sí (no seguro para subprocesos) |
NumberFormat.getCurrencyInstance | dinero | sí | sí |
NumberFormat.getPercentInstance | proporciones | sí | sí |
Un ejemplo completo y ejecutable
El programa a continuación formatea el mismo número de cuatro maneras diferentes y luego muestra el relleno con ceros, para que puedas comparar las salidas lado a lado.
Lo que se puede observar en la ejecución:
printfcon%,.2fimprime1,234,567.89, añadiendo separadores de agrupación y fijando dos decimales.DecimalFormat("#,##0.00")produce el mismo1,234,567.89pero como una cadena reutilizable y retornable.getCurrencyInstance(Locale.US)antepone el símbolo$para dar$1,234,567.89.getPercentInstancemultiplica0.8736por 100 y lo redondea a87%.%08.2frellena con ceros42.5hasta el ancho 8, imprimiendo00042.50.