¿Cómo formatear cantidades de moneda negativas con paréntesis para contabilidad?

Usa la opción currencySign para mostrar valores de moneda negativos en notación contable

Introducción

Los estados financieros, informes contables y balances muestran las cantidades de moneda negativas entre paréntesis en lugar de con signos menos. Una pérdida de quinientos dólares aparece como ($500.00) en lugar de -$500.00. Esta convención hace que las cantidades negativas sean más visualmente distintas, reduce el riesgo de pasar por alto pérdidas y sigue los estándares contables establecidos.

La API Intl.NumberFormat de JavaScript proporciona la opción currencySign para formatear cantidades de moneda negativas en esta notación contable. Cuando estableces currencySign en "accounting", los valores negativos se muestran automáticamente entre paréntesis según las convenciones locales.

Por qué la notación contable usa paréntesis

La práctica de envolver cantidades negativas entre paréntesis se originó antes de que las computadoras se volvieran comunes en contabilidad. Un signo menos impreso en papel podía ser pequeño, tenue o fácil de pasar por alto al escanear columnas de números. Los paréntesis crean un límite visual claro alrededor de los valores negativos, haciéndolos inmediatamente reconocibles.

Los paréntesis también evitan confusión con guiones que aparecen en otros contextos. En tablas financieras densas con muchas filas y columnas, los paréntesis destacan más que un solo carácter de signo menos. Esta distinción visual ayuda a prevenir errores al leer, transcribir o analizar datos financieros.

La convención se convirtió en práctica estándar en contabilidad y sigue siendo ampliamente utilizada hoy en día. La mayoría del software contable, informes financieros y balances muestran cantidades negativas entre paréntesis. Los usuarios familiarizados con documentos financieros esperan este formato y lo encuentran más fácil de leer que los signos menos.

Uso del formato contable currencySign

Pasa la opción currencySign con el valor "accounting" al crear una instancia de Intl.NumberFormat para formateo de moneda. Esto le indica al formateador que use notación contable para cantidades negativas.

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

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

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

La cantidad negativa se muestra entre paréntesis sin signo menos. Las cantidades positivas se muestran normalmente sin paréntesis. El formateador aplica la notación contable apropiada automáticamente según si el valor es positivo o negativo.

La opción currencySign solo afecta al formateo de moneda. Debes establecer style: 'currency' y proporcionar un código currency para que la opción surta efecto.

Comparación de formatos estándar y contable

El formato de moneda predeterminado usa un signo menos para valores negativos. Este formato estándar funciona bien para propósitos generales, mientras que el formato contable sigue las convenciones de informes financieros.

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

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

console.log(standard.format(-500));
// Output: "-$500.00"

console.log(accounting.format(-500));
// Output: "($500.00)"

El formato estándar coloca un signo menos antes del símbolo de moneda. El formato contable envuelve la cantidad completa, incluido el símbolo de moneda, entre paréntesis. Ambos formatos producen la misma salida para valores positivos.

Si omites la opción currencySign, el formateador usa por defecto el comportamiento "standard".

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

console.log(formatter.format(-500));
// Output: "-$500.00"

Cómo varía la notación contable según la configuración regional

Diferentes configuraciones regionales colocan el símbolo de moneda y los paréntesis en diferentes posiciones según las convenciones locales. La API Intl.NumberFormat maneja estas variaciones automáticamente.

const currencies = [
  { locale: 'en-US', currency: 'USD' },
  { locale: 'de-DE', currency: 'EUR' },
  { locale: 'fr-FR', currency: 'EUR' },
  { locale: 'ja-JP', currency: 'JPY' }
];

currencies.forEach(({ locale, currency }) => {
  const formatter = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency,
    currencySign: 'accounting'
  });

  console.log(`${locale}: ${formatter.format(-1234.56)}`);
});

// Output:
// en-US: ($1,234.56)
// de-DE: (-1.234,56 €)
// fr-FR: (1 234,56 €)
// ja-JP: (¥-1,235)

Cada configuración regional formatea la cantidad negativa según sus convenciones para la colocación del símbolo de moneda, separadores decimales, separadores de miles y uso de paréntesis. No necesitas conocer estas convenciones ni implementarlas manualmente. La API aplica el formato correcto según el identificador de configuración regional.

Algunas configuraciones regionales colocan el signo menos dentro de los paréntesis cerca del número. Otras lo colocan cerca del símbolo de moneda. El formateador maneja estos detalles según las reglas específicas de cada configuración regional.

Combinación de notación contable con opciones de visualización de signo

La opción currencySign funciona junto con la opción signDisplay para controlar cómo aparecen los signos en el formateo de moneda. Esta combinación te da un control preciso sobre la visualización de cantidades positivas y negativas.

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

console.log(always.format(500));
// Output: "+$500.00"

console.log(always.format(-500));
// Output: "($500.00)"

Con signDisplay: 'always', las cantidades positivas se muestran con un signo más mientras que las cantidades negativas siguen usando paréntesis. Esto hace que tanto las ganancias como las pérdidas sean explícitas.

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

console.log(never.format(500));
// Output: "$500.00"

console.log(never.format(-500));
// Output: "$500.00"

Con signDisplay: 'never', tanto las cantidades positivas como las negativas se muestran de forma idéntica sin signos ni paréntesis. Esto muestra solo la magnitud independientemente de si el valor es positivo o negativo.

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

console.log(exceptZero.format(500));
// Output: "+$500.00"

console.log(exceptZero.format(-500));
// Output: "($500.00)"

console.log(exceptZero.format(0));
// Output: "$0.00"

Con signDisplay: 'exceptZero', las cantidades positivas muestran un signo más, las cantidades negativas usan paréntesis y el cero se muestra sin ningún signo. Este formato funciona bien para estados de pérdidas y ganancias donde se desea enfatizar los cambios mientras se mantiene el cero neutral.

Cuándo usar el formato contable

Usa el formato contable al mostrar datos financieros en contextos donde los usuarios esperan convenciones contables. Esto incluye estados financieros, balances generales, estados de resultados, informes de pérdidas y ganancias e interfaces de software contable.

El formato contable hace que las cantidades negativas sean más prominentes que el formato estándar. Los paréntesis crean un límite visual que atrae la atención hacia las pérdidas, deudas o saldos negativos. Esto ayuda a los usuarios a identificar rápidamente áreas problemáticas al escanear datos financieros.

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

const accounts = [
  { name: 'Cash', balance: 15000 },
  { name: 'Accounts Receivable', balance: -3500 },
  { name: 'Inventory', balance: 12000 },
  { name: 'Accounts Payable', balance: -8000 }
];

accounts.forEach(account => {
  const formatted = accountingFormatter.format(account.balance);
  console.log(`${account.name}: ${formatted}`);
});

// Output:
// Cash: $15,000.00
// Accounts Receivable: ($3,500.00)
// Inventory: $12,000.00
// Accounts Payable: ($8,000.00)

Los paréntesis hacen que los saldos negativos destaquen, ayudando a los usuarios a identificar cuentas con valores negativos de un vistazo.

Usa el formato estándar para comercio electrónico general, interfaces orientadas al consumidor o contextos donde las convenciones contables no aplican. La mayoría de los usuarios fuera de la contabilidad y las finanzas están menos familiarizados con la notación entre paréntesis y esperan ver signos menos para las cantidades negativas.

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

// For a shopping cart or refund:
console.log(standardFormatter.format(-25.50));
// Output: "-$25.50"

Elige el formato contable cuando tu audiencia espera convenciones de informes financieros. Elige el formato estándar cuando tu audiencia espera visualizaciones orientadas al consumidor. Ajusta el formato a las expectativas de tus usuarios y al contexto donde aparecen los números.

Compatibilidad del navegador con el formato contable

La opción currencySign: "accounting" es compatible con todos los navegadores modernos. Chrome, Edge, Firefox, Safari y sus versiones móviles admiten esta función en las versiones lanzadas desde 2019.

Si necesitas admitir navegadores más antiguos, prueba la función y proporciona una alternativa.

function formatCurrency(amount) {
  try {
    const formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      currencySign: 'accounting'
    });
    return formatter.format(amount);
  } catch (error) {
    // Fallback for browsers without accounting support
    const formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD'
    });
    return formatter.format(amount);
  }
}

Esta alternativa devuelve el formato de moneda estándar si el formato contable no está disponible. En la práctica, la compatibilidad con el formato contable es lo suficientemente amplia como para que esta alternativa rara vez sea necesaria para aplicaciones que solo admiten navegadores modernos.