Intl.NumberFormat ya sea 0 o dos dígitos de fracción

4 minutos de lectura

Mi formateador se ve así

const formatter = new Intl.NumberFormat('en-NZ', {
  style: 'currency',
  currency: 'NZD',
  minimumFractionDigits: 2,
});

¿Cómo puedo ajustar esto para que los números enteros tengan 0 dígitos fraccionarios?

formatter.format(4); // want output "$4"

mientras que las fracciones siempre muestran dos dígitos?

formatter.format(4.1); // want output "$4.10"

La forma correcta de hacerlo cuando se usa Intl.NumberFormat es configurar ambos máximoFractionDigits y mínimoFractionDigits opciones en el constructor al validar el valor de entrada usando un módulo% para un número entero (por https://stackoverflow.com/a/49724586/1362535 que es una respuesta CORRECTA!). La respuesta aceptada es una especie de manipulación de cadenas.

const fraction = new Intl.NumberFormat('en-NZ', {
  style: 'currency',
  currency: 'NZD',
  minimumFractionDigits: 0,
  maximumFractionDigits: 0,
});

const formatter = new Intl.NumberFormat('en-NZ', {
  style: 'currency',
  currency: 'NZD',
  minimumFractionDigits: 2,
});

let number = 4.1;
  if(number % 1 == 0)
console.log(fraction.format(number));
  else
console.log(formatter.format(number));

number = 4;
  if(number % 1 == 0)
console.log(fraction.format(number));
  else
console.log(formatter.format(number));

  • Usar dígitos de fracción mínimos y máximos es la forma correcta cuando se usa Intl.NumberFormat

    – sintaxis

    14 de julio de 2020 a las 0:40

  • no hay opción maximumFractionDigits que existe

    – Ari Seyhun

    13 de agosto de 2020 a las 8:00

  • @ Acidic9 echa un vistazo aquí desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – crtag

    14 de agosto de 2020 a las 5:51

  • @ Acidic9 ¿trataste de usar solo maximumFractionDigits? Encontré que da un error que no usa ambos.

    –Jeff Bluemel

    26 de agosto de 2020 a las 2:49

  • Esto no maneja el caso donde el formato da como resultado un número entero. 1234.999 daría como resultado 1235,00

    – olefrán

    11 de noviembre de 2022 a las 8:57

avatar de usuario de kshetline
kshetline

Podrías intentar algo como esto:

formatter.format(amount).replace(/\D00$/, '');

Actualizar:

En respuesta al comentario de muchos meses después de @Marek, la expresión regular anterior ya maneja diferentes símbolos decimales (ya sea . o ,), pero es cierto que no maneja símbolos de moneda finales. Eso se puede arreglar de esta manera:

formatter.format(amount).replace(/\D00(?=\D*$)/, '');

  • La solución propuesta no funcionará en algunas configuraciones regionales donde el formateador agrega en lugar de anteponer el código/símbolo de moneda. Por ejemplo sk lugar y EUR producción de moneda 12,50 €. Además, debe considerar diferentes separadores de fracciones (coma, punto). En ese caso, podrías usar formatToParts en vez de format método que produce una matriz donde cada fragmento se identifica de forma única. Entonces todo lo que necesita hacer es filtrar condicionalmente el fraction y decimal fragmentos

    –Marek Suscak

    21 de enero de 2019 a las 12:06


  • Solo una pregunta, para la configuración regional en-us, ¿por qué necesitaría una expresión regular? no es .replace('.00', '') simplemente suficiente?

    – ViBoNaCci

    16 de abril de 2020 a las 11:12


  • @ViBoNaCci, sí, si no le importara manejar otras configuraciones regionales, podría prescindir de la expresión regular. La expresión regular está destinada a tratar con un punto o una coma como símbolo decimal.

    – kshetline

    16 de abril de 2020 a las 14:20

  • @ViBoNaCci también tenga cuidado con el reemplazo directo, porque lo reemplazará en cualquier parte del número, no solo al final.

    – Jordán Morris

    19 de mayo de 2020 a las 10:45

  • @JordanMorris Cierto. Pero en en-us, el punto está separado por decimales, por lo que el reemplazo debe ser resistente al agua, dado que es solo para en-us.

    – ViBoNaCci

    5 de marzo de 2021 a las 12:40

Avatar de usuario de Gerardo BLANCO
Gerardo BLANCO

Implementaría dos formatos diferentes y lo validaría usando un módulo %

4 % 1 == 0
4.1 % 1 == .1

Espero que esto ayude 🙂

const formatter = new Intl.NumberFormat('en-NZ', {
  style: 'currency',
  currency: 'NZD',
  minimumFractionDigits: 2,
});

const fraction = new Intl.NumberFormat('en-NZ', {
  style: 'currency',
  currency: 'NZD',
  minimumFractionDigits: 0,
});


let number = 4.1;
  if(number % 1 == 0)
console.log(fraction.format(number));
  else
console.log(formatter.format(number));


number = 4;
  if(number % 1 == 0)
console.log(fraction.format(number));
  else
console.log(formatter.format(number));

  • me parece la opcion mas segura

    – H77

    9 de abril de 2018 a las 2:21

  • Este ejemplo no logra el objetivo del autor de la pregunta: “ya sea 0 o dos dígitos de fracción”

    – Michael R.

    9 de abril de 2019 a las 1:46

  • Lo hace, puede probar y editar el number en el fragmento para ver la funcionalidad

    – Gerardo BLANCO

    10 de abril de 2019 a las 12:40

Cuando investigué esto, encontré una publicación en Github al respecto que sugiere usar los máximosFractionDigits y los mínimosFractionDigits. El artículo establece que si no se usan ambos, arrojaría un error.

// works
var Intl = require('intl');
new Intl.NumberFormat("en", { 
  maximumFractionDigits: 0, 
  minimumFractionDigits: 0, 
  style: 'currency', 
  currency: 'USD'
}).format(4000.33)

https://github.com/ember-intl/ember-intl/issues/167

Parece que hoy en día, la forma más fácil es simplemente establecer “minimumFractionDigits” en 0 y “maximumFractionDigits” en 2, así:

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'usd',
  maximumFractionDigits: 2,
  minimumFractionDigits: 0,
}); 

console.log('No decimals: ', formatter.format(1000));
console.log('Decimals: ', formatter.format(999.99));

¿Ha sido útil esta solución?