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

Utiliza la opción currencySign para mostrar valores monetarios negativos en notación contable

Introducción

Los estados financieros, informes contables y balances muestran las cantidades monetarias negativas entre paréntesis en lugar de con signos negativos. 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 visualmente más distintivas, reduce el riesgo de pasar por alto las pérdidas y sigue los estándares contables establecidos.

La API Intl.NumberFormat de JavaScript proporciona la opción currencySign para formatear cantidades monetarias negativas en esta notación contable. Cuando estableces currencySign como "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 encerrar cantidades negativas entre paréntesis se originó antes de que las computadoras se volvieran comunes en la contabilidad. Un signo menos impreso en papel podía ser pequeño, tenue o fácilmente pasado 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 la confusión con guiones o rayas 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 una 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.

Usando el formato contable currencySign

Pasa la opción currencySign con el valor "accounting" al crear una instancia de Intl.NumberFormat para el formateo de moneda. Esto le indica al formateador que use la 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));
// Resultado: "($1,234.56)"

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

La cantidad negativa se muestra envuelta en paréntesis sin un signo menos. Las cantidades positivas se muestran normalmente sin paréntesis. El formateador aplica automáticamente la notación contable apropiada 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 de currency para que la opción tenga efecto.

Comparación de formatos estándar y contables

El formato de moneda predeterminado utiliza 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 el monto completo, 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 utiliza 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 el monto negativo 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 basado en 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 basándose en reglas específicas de cada configuración regional.

Combinando la notación contable con opciones de visualización de signos

La opción currencySign funciona junto con la opción signDisplay para controlar cómo aparecen los signos en el formato 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 negativas se muestran de manera 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 quieres enfatizar los cambios mientras mantienes el cero neutral.

Cuándo usar el formato contable

Utiliza el formato contable cuando muestres datos financieros en contextos donde los usuarios esperan convenciones contables. Esto incluye estados financieros, balances, cuentas de resultados, informes de pérdidas y ganancias, e interfaces de software de contabilidad.

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 llama la atención sobre 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.

Utiliza el formato estándar para comercio electrónico general, interfaces orientadas al consumidor o contextos donde no se aplican las convenciones contables. 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 cantidades negativas.

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

// Para un carrito de compras o reembolso:
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. Adapta el formato a las expectativas de tus usuarios y al contexto donde aparecen los números.

Compatibilidad de navegadores para 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 versiones lanzadas desde 2019.

Si necesitas compatibilidad con 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) {
    // Alternativa para navegadores sin soporte para formato contable
    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 está lo suficientemente extendida como para que esta alternativa rara vez sea necesaria para aplicaciones que solo admiten navegadores modernos.