Saltar al contenido principal

`Intl.NumberFormat`

· 4 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias)) y Shane F. Carr

Es posible que ya estés familiarizado con la API Intl.NumberFormat, ya que ha sido compatible con varios entornos modernos durante algún tiempo.

En su forma más básica, Intl.NumberFormat te permite crear una instancia de formato reutilizable que admite el formato de números adaptado al idioma. Al igual que otras APIs de Intl.*Format, una instancia de formateador admite ambos métodos: format y formatToParts:

const formatter = new Intl.NumberFormat('en');
formatter.format(987654.321);
// → '987,654.321'
formatter.formatToParts(987654.321);
// → [
// → { type: 'integer', value: '987' },
// → { type: 'group', value: ',' },
// → { type: 'integer', value: '654' },
// → { type: 'decimal', value: '.' },
// → { type: 'fraction', value: '321' }
// → ]

Nota: Aunque gran parte de la funcionalidad de Intl.NumberFormat se puede lograr utilizando Number.prototype.toLocaleString, Intl.NumberFormat suele ser la mejor opción, ya que permite crear una instancia de formato reutilizable que tiende a ser más eficiente.

Recientemente, la API Intl.NumberFormat ha adquirido nuevas capacidades.

Compatibilidad con BigInt

Además de los Numbers, Intl.NumberFormat ahora también puede formatear BigInts:

const formatter = new Intl.NumberFormat('fr');
formatter.format(12345678901234567890n);
// → '12 345 678 901 234 567 890'
formatter.formatToParts(123456n);
// → [
// → { type: 'integer', value: '123' },
// → { type: 'group', value: ' ' },
// → { type: 'integer', value: '456' }
// → ]

Unidades de medida

Intl.NumberFormat actualmente admite las siguientes unidades simples:

  • ángulo: degree
  • área: acre, hectare
  • concentración: percent
  • digital: bit, byte, kilobit, kilobyte, megabit, megabyte, gigabit, gigabyte, terabit, terabyte, petabyte
  • duración: millisecond, second, minute, hour, day, week, month, year
  • longitud: millimeter, centimeter, meter, kilometer, inch, foot, yard, mile, mile-scandinavian
  • masa: gram, kilogram, ounce, pound, stone
  • temperatura: celsius, fahrenheit
  • volumen: liter, milliliter, gallon, fluid-ounce

Para formatear números con unidades localizadas, utiliza las opciones style y unit:

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'kilobyte',
});
formatter.format(1.234);
// → '1.234 kB'
formatter.format(123.4);
// → '123.4 kB'

Ten en cuenta que con el tiempo se pueden agregar más unidades. Por favor, consulta la especificación para la lista más actualizada.

Las unidades simples mencionadas anteriormente se pueden combinar en pares arbitrarios de numerador y denominador para expresar unidades compuestas como “litros por acre” o “metros por segundo”:

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
});
formatter.format(299792458);
// → '299,792,458 m/s'

Notación compacta, científica e ingenieril

La notación compacta utiliza símbolos específicos del idioma para representar números grandes. Es una alternativa más amigable para humanos a la notación científica:

{
// Prueba la notación estándar.
const formatter = new Intl.NumberFormat('en', {
notation: 'standard', // Este es el valor predeterminado implícito.
});
formatter.format(1234.56);
// → '1,234.56'
formatter.format(123456);
// → '123,456'
formatter.format(123456789);
// → '123,456,789'
}

{
// Prueba la notación compacta.
const formatter = new Intl.NumberFormat('en', {
notation: 'compact',
});
formatter.format(1234.56);
// → '1.2K'
formatter.format(123456);
// → '123K'
formatter.format(123456789);
// → '123M'
}

Nota: De forma predeterminada, la notación compacta redondea al número entero más cercano, pero siempre conserva 2 dígitos significativos. Puedes configurar cualquiera de {minimum,maximum}FractionDigits o {minimum,maximum}SignificantDigits para anular ese comportamiento.

Intl.NumberFormat también puede formatear números en notación científica:

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
notation: 'scientific',
});
formatter.format(299792458);
// → '2.998E8 m/s'

La notación de ingeniería también es compatible:

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
notation: 'engineering',
});
formatter.format(299792458);
// → '299.792E6 m/s'

Mostrar signo

En ciertas situaciones (como presentar diferencias) ayuda mostrar explícitamente el signo, incluso cuando el número es positivo. La nueva opción signDisplay lo permite:

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'percent',
signDisplay: 'always',
});
formatter.format(-12.34);
// → '-12.34%'
formatter.format(12.34);
// → '+12.34%'
formatter.format(0);
// → '+0%'
formatter.format(-0);
// → '-0%'

Para evitar mostrar el signo cuando el valor es 0, usa signDisplay: 'exceptZero':

const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'percent',
signDisplay: 'exceptZero',
});
formatter.format(-12.34);
// → '-12.34%'
formatter.format(12.34);
// → '+12.34%'
formatter.format(0);
// → '0%'
// Nota: -0 aún se muestra con signo, como se espera:
formatter.format(-0);
// → '-0%'

Para monedas, la opción currencySign permite el formato contable, que habilita un formato específico por ubicación para cantidades negativas de moneda; por ejemplo, envolver la cantidad en paréntesis:

const formatter = new Intl.NumberFormat('en', {
style: 'currency',
currency: 'USD',
signDisplay: 'exceptZero',
currencySign: 'accounting',
});
formatter.format(-12.34);
// → '($12.34)'
formatter.format(12.34);
// → '+$12.34'
formatter.format(0);
// → '$0.00'
formatter.format(-0);
// → '($0.00)'

Más información

La propuesta de especificación correspondiente tiene más información y ejemplos, incluida orientación sobre cómo detectar características individuales de Intl.NumberFormat.