Cómo formatear monedas con símbolos específicos de configuración regional

Muestra precios con el símbolo de moneda, posición y formato correctos para cualquier configuración regional

Introducción

Los símbolos de moneda identifican qué moneda representa un precio. El signo de dólar indica dólares estadounidenses, el símbolo del euro indica euros y el signo de libra indica libras esterlinas. Estos símbolos son esenciales para aplicaciones internacionales porque los usuarios necesitan saber qué moneda están viendo o gastando.

Diferentes países formatean las cantidades monetarias de manera diferente. Los estadounidenses escriben $1,234.56 con el símbolo antes de la cantidad. Los alemanes escriben 1.234,56 € con el símbolo después de la cantidad y diferentes separadores. El formato francés usa 1 234,56 € con espacios entre grupos de dígitos. Cuando codificas el formato de moneda de forma fija como "$" + amount, asumes que todos los usuarios siguen las mismas convenciones.

JavaScript proporciona la API Intl.NumberFormat para formatear cantidades monetarias con símbolos y convenciones apropiados para la configuración regional. Esta lección explica cómo varía el formato de moneda según la configuración regional y cómo formatear precios correctamente para cualquier idioma o región.

Los símbolos de moneda varían según la configuración regional

Diferentes monedas usan diferentes símbolos. El dólar estadounidense usa $, el euro usa €, la libra esterlina usa £, el yen japonés usa ¥ y el franco suizo usa Fr. o CHF dependiendo del contexto. Cada símbolo ayuda a los usuarios a identificar rápidamente qué moneda están viendo.

Algunos símbolos representan múltiples monedas. El signo de dólar $ se usa para dólares estadounidenses, dólares canadienses, dólares australianos, pesos mexicanos y varias otras monedas. Sin contexto adicional, los usuarios no pueden distinguir qué moneda en dólares representa un precio.

La posición del símbolo de moneda varía según la configuración regional. Los países de habla inglesa típicamente colocan el símbolo antes de la cantidad como $100. Muchos países europeos colocan el símbolo después de la cantidad como 100 €. Algunos países incluyen un espacio entre la cantidad y el símbolo mientras que otros no.

Estas diferencias significan que no puedes simplemente concatenar un símbolo y un número. Necesitas lógica de formato que comprenda tanto la moneda que se muestra como la configuración regional del usuario que la visualiza.

Formatear moneda con Intl.NumberFormat

El constructor Intl.NumberFormat crea un formateador de moneda cuando pasas style: 'currency' en las opciones. También debes especificar qué moneda formatear usando la opción currency con un código de moneda ISO 4217.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// Output: "$1,234.56"

Esto crea un formateador para inglés estadounidense que muestra importes en dólares estadounidenses. El método format() convierte el número en una cadena con el símbolo del dólar, separadores de miles y dos decimales.

La opción currency requiere un código ISO 4217 de tres letras. Los códigos comunes incluyen USD para dólares estadounidenses, EUR para euros, GBP para libras esterlinas, JPY para yenes japoneses y CAD para dólares canadienses.

const usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
// Output: "$100.00"

console.log(eurFormatter.format(100));
// Output: "€100.00"

console.log(gbpFormatter.format(100));
// Output: "£100.00"

Cada formateador inserta automáticamente el símbolo de moneda apropiado. No necesitas saber qué símbolo corresponde a cada código de moneda.

La configuración regional determina la posición del símbolo y el formato

El parámetro de configuración regional controla cómo se formatean los importes de moneda, incluyendo la posición del símbolo, la agrupación de dígitos y los separadores decimales. El mismo código de moneda produce diferentes resultados dependiendo de la configuración regional.

const usFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const deFormatter = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});

const frFormatter = new Intl.NumberFormat('fr-FR', {
  style: 'currency',
  currency: 'EUR'
});

console.log(usFormatter.format(1234.56));
// Output: "€1,234.56"

console.log(deFormatter.format(1234.56));
// Output: "1.234,56 €"

console.log(frFormatter.format(1234.56));
// Output: "1 234,56 €"

Los tres formateadores muestran euros, pero cada uno usa convenciones diferentes. El formateador de inglés estadounidense coloca el símbolo antes del importe con un punto como separador decimal. El formateador alemán coloca el símbolo después del importe con un espacio, usa puntos para separadores de miles y usa una coma como separador decimal. El formateador francés usa espacios para separadores de miles.

La API Intl gestiona estas diferencias automáticamente según la configuración regional que especifiques. No necesitas conocer las reglas de formato para cada configuración regional.

El formato de moneda incluye decimales

Los formateadores de moneda determinan automáticamente el número apropiado de decimales según la moneda. La mayoría de las monedas utilizan dos decimales para centavos o fracciones equivalentes.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(100));
// Output: "$100.00"

console.log(formatter.format(100.5));
// Output: "$100.50"

console.log(formatter.format(100.567));
// Output: "$100.57"

El formateador siempre muestra dos decimales para dólares estadounidenses, rellenando con ceros cuando es necesario y redondeando cuando la entrada tiene más precisión.

Algunas monedas tienen cero decimales. El yen japonés no tiene una unidad fraccionaria, por lo que las cantidades se muestran sin decimales.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'JPY'
});

console.log(formatter.format(1234.56));
// Output: "¥1,235"

El formateador redondea al número entero más cercano porque las cantidades en yenes no incluyen unidades fraccionarias. La API Intl conoce la precisión decimal de cada moneda y la aplica automáticamente.

Formatear moneda según la configuración regional del usuario

En lugar de codificar una configuración regional específica, puedes usar las preferencias de idioma del navegador del usuario. La propiedad navigator.language devuelve la configuración regional preferida del usuario.

const userLocale = navigator.language;

const formatter = new Intl.NumberFormat(userLocale, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// Output varies by user's locale
// For en-US: "$1,234.56"
// For de-DE: "1.234,56 $"
// For fr-FR: "1 234,56 $US"

Este enfoque muestra las cantidades de moneda según las expectativas de formato de cada usuario. Un usuario alemán ve el símbolo después de la cantidad con separadores alemanes, mientras que un usuario estadounidense ve el símbolo antes de la cantidad con separadores estadounidenses.

También puedes pasar el array completo navigator.languages para habilitar el comportamiento de respaldo cuando la preferencia principal del usuario no esté disponible.

const formatter = new Intl.NumberFormat(navigator.languages, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));

La API utiliza la primera configuración regional que admite del array, proporcionando gestión automática de respaldo.

Reutilizar formateadores de moneda

Crear una nueva instancia de Intl.NumberFormat implica cargar datos de configuración regional y procesar opciones. Cuando formateas múltiples precios con la misma configuración regional y moneda, crea el formateador una vez y reutilízalo.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const prices = [19.99, 29.99, 49.99, 99.99];

prices.forEach(price => {
  console.log(formatter.format(price));
});
// Output:
// "$19.99"
// "$29.99"
// "$49.99"
// "$99.99"

Este patrón es más eficiente que crear un nuevo formateador para cada precio. La diferencia de rendimiento se vuelve significativa al formatear arrays o listas con muchos valores.

Mostrar precios en aplicaciones

Puedes usar formateadores de moneda en cualquier lugar donde muestres precios a los usuarios. Esto incluye listados de productos, carritos de compra, páginas de pago, facturas y paneles financieros.

const formatter = new Intl.NumberFormat(navigator.language, {
  style: 'currency',
  currency: 'USD'
});

const productPrice = 29.99;
const taxAmount = 2.40;
const totalPrice = productPrice + taxAmount;

document.getElementById('product-price').textContent = formatter.format(productPrice);
document.getElementById('tax-amount').textContent = formatter.format(taxAmount);
document.getElementById('total-price').textContent = formatter.format(totalPrice);

Las cadenas formateadas funcionan como cualquier otro valor de cadena. Puedes insertarlas en contenido de texto, atributos o cualquier contexto donde muestres información a los usuarios.

Gestionar múltiples monedas

Las aplicaciones que admiten múltiples monedas necesitan crear formateadores separados para cada moneda. El código de moneda determina qué símbolo aparece, mientras que la configuración regional determina cómo se formatea el importe.

const locale = navigator.language;

const usdFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
console.log(eurFormatter.format(100));
console.log(gbpFormatter.format(100));

Cada formateador muestra el símbolo apropiado y sigue las convenciones de configuración regional del usuario para esa moneda. Esto garantiza que los precios sean precisos y legibles independientemente de la combinación de moneda o configuración regional que se utilice.