W3docs

API Intl (Internacionalización) de JavaScript

Aprende la API Intl integrada de JavaScript para formatear números, monedas, fechas, tiempos relativos, listas y plurales para cualquier locale, y ordenar cadenas correctamente con comparación sensible al locale.

Intl es un espacio de nombres integrado de JavaScript para formateo y comparación sensibles al locale. No hay ninguna librería que instalar ni nada que importar: viene incluido en todos los navegadores modernos y en Node.js. Con él puedes formatear números, monedas, fechas, tiempos relativos y listas exactamente como los usuarios de una región determinada esperan, y puedes ordenar texto correctamente para idiomas en los que la ordenación solo en inglés produce resultados incorrectos.

Casi todos los constructores de Intl siguen la misma forma: pasas un locale (o un array de locales de respaldo) y un objeto de opciones. Un locale es una etiqueta de idioma BCP 47 como 'en-US', 'de-DE', 'fr-FR' o 'ja-JP'. Si omites el locale por completo, Intl utiliza el locale predeterminado del entorno de ejecución (la configuración de idioma del navegador, o el locale del sistema en Node).

// locale + options
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });

// no locale → uses the runtime default
new Intl.NumberFormat();

// an array provides fallbacks: try Welsh, then fall back to English
new Intl.NumberFormat(['cy', 'en']);

Intl.NumberFormat

Intl.NumberFormat formatea números según las convenciones de un locale. Esto importa porque los separadores de agrupación y decimales varían de un lugar a otro: el número 1234.56 se escribe 1,234.56 en Estados Unidos pero 1.234,56 en Alemania.

const n = 1234.56;

console.log(new Intl.NumberFormat('en-US').format(n)); // "1,234.56"
console.log(new Intl.NumberFormat('de-DE').format(n)); // "1.234,56"
console.log(new Intl.NumberFormat('fr-FR').format(n)); // "1 234,56"

La opción style selecciona el tipo de valor que estás formateando: 'decimal' (el predeterminado), 'currency', 'percent' o 'unit'.

Moneda

Para dinero, establece style: 'currency' y nombra la moneda con la opción currency (un código ISO 4217 como 'USD' o 'EUR'). El locale decide la posición del símbolo y los separadores.

const price = 1499.9;

console.log(
  new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
); // "$1,499.90"

console.log(
  new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price)
); // "1.499,90 €"

console.log(
  new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(price)
); // "¥1,500"   (yen has no minor unit, so it is rounded)

Porcentaje, dígitos fraccionarios y notación compacta

Usa style: 'percent' para formatear una proporción como porcentaje — el valor se multiplica por 100. Controla cuántos decimales aparecen con minimumFractionDigits y maximumFractionDigits. Establece notation: 'compact' para producir formas cortas como 1.2K y 3.4M.

console.log(
  new Intl.NumberFormat('en-US', { style: 'percent' }).format(0.1875)
); // "19%"

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'percent',
    minimumFractionDigits: 2,
  }).format(0.1875)
); // "18.75%"

console.log(
  new Intl.NumberFormat('en-US', { notation: 'compact' }).format(1200000)
); // "1.2M"

Unidades

Con style: 'unit' puedes formatear medidas. Nombra la unidad con la opción unit (por ejemplo 'kilometer-per-hour' o 'megabyte') y elige un unitDisplay de 'short', 'long' o 'narrow'.

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'unit',
    unit: 'kilometer-per-hour',
  }).format(90)
); // "90 km/h"

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'unit',
    unit: 'megabyte',
    unitDisplay: 'long',
  }).format(16)
); // "16 megabytes"

Para trabajo más profundo con números — redondeo, precisión y aritmética — consulta Numbers y JavaScript Math.

Intl.DateTimeFormat

Intl.DateTimeFormat formatea objetos Date (y marcas de tiempo) para un locale. El enfoque más rápido son las opciones dateStyle y timeStyle, cada una de las cuales acepta 'full', 'long', 'medium' o 'short'.

javascript— editable

Para un control más preciso, establece componentes individuales como year, month, day, hour, minute y second, y fija la salida a una zona con timeZone.

const date = new Date('2026-06-19T14:30:00Z');

const fmt = new Intl.DateTimeFormat('en-GB', {
  year: 'numeric',
  month: 'short',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  timeZone: 'Europe/Berlin',
});

console.log(fmt.format(date)); // "19 Jun 2026, 16:30"

Dos métodos adicionales vale la pena conocer. .formatToParts() devuelve la salida dividida en partes etiquetadas ({ type: 'month', value: 'Jun' }, etc.), lo que te permite dar estilo a partes individuales. .formatRange(start, end) formatea un rango de fechas de forma compacta, eliminando las partes compartidas.

const fmt = new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' });

console.log(fmt.formatRange(new Date(2026, 5, 1), new Date(2026, 5, 5)));
// "June 1 – 5"

Para todo sobre la creación y manipulación de fechas, consulta JavaScript Date.

Intl.RelativeTimeFormat

Intl.RelativeTimeFormat produce frases en lenguaje natural como "hace 2 días" o "en 3 horas". Llamas a .format(value, unit), donde un value negativo está en el pasado y un value positivo está en el futuro. La opción numeric: 'auto' permite que el formateador use palabras como "ayer" y "mañana" en lugar de "hace 1 día".

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

console.log(rtf.format(-1, 'day'));  // "yesterday"
console.log(rtf.format(3, 'hour'));  // "in 3 hours"
console.log(rtf.format(-2, 'day'));  // "2 days ago"
console.log(rtf.format(1, 'week'));  // "next week"

La misma llamada en otro locale produce frases nativas — new Intl.RelativeTimeFormat('fr').format(-1, 'day') da "il y a 1 jour".

Intl.Collator

Ordenar texto es el lugar donde el código ingenuo más a menudo falla. El Array.prototype.sort() predeterminado de JavaScript compara cadenas por sus unidades de código UTF-16, no por reglas alfabéticas. Eso significa que las letras mayúsculas se ordenan antes que las minúsculas, y las letras acentuadas o no latinas acaban en lugares sorprendentes.

const words = ['Zürich', 'apple', 'Banana', 'Älpler'];

console.log([...words].sort());
// ["Banana", "Zürich", "Älpler", "apple"]  ← not what a reader expects

Intl.Collator corrige esto comparando cadenas de la forma en que lo hace un idioma determinado. Su método .compare tiene exactamente la firma que sort() espera, por lo que puedes pasarlo directamente.

javascript— editable

Para una comparación puntual de dos cadenas también puedes usar String.prototype.localeCompare, que acepta los mismos argumentos de locale y opciones: 'ä'.localeCompare('z', 'de'). Cuando estás ordenando un array completo, prefiere un Intl.Collator reutilizado — es más rápido que llamar a localeCompare en cada par. Consulta Strings para más información sobre cómo trabajar con texto.

Intl.PluralRules

Los distintos idiomas tienen diferentes categorías de plural. El inglés solo tiene dos ('one' y 'other'), pero muchos idiomas tienen más. Intl.PluralRules te indica en qué categoría cae un número para que puedas seleccionar la redacción correcta en un mensaje traducido.

const pr = new Intl.PluralRules('en-US');

console.log(pr.select(0)); // "other"
console.log(pr.select(1)); // "one"
console.log(pr.select(5)); // "other"

function items(count) {
  const word = pr.select(count) === 'one' ? 'item' : 'items';
  return `${count} ${word}`;
}

console.log(items(1)); // "1 item"
console.log(items(3)); // "3 items"

Intl.ListFormat

Intl.ListFormat une un array de cadenas en una lista que suena natural, insertando los separadores y la conjunción correctos para el locale — incluida la coma de Oxford donde el idioma la utiliza.

const items = ['apples', 'bananas', 'oranges'];

const en = new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' });
console.log(en.format(items)); // "apples, bananas, and oranges"

const enOr = new Intl.ListFormat('en-US', { type: 'disjunction' });
console.log(enOr.format(items)); // "apples, bananas, or oranges"

const de = new Intl.ListFormat('de-DE', { type: 'conjunction' });
console.log(de.format(items)); // "apples, bananas und oranges"

Reutilizar formateadores para mejor rendimiento

Advertencia

Construir un formateador Intl es comparativamente costoso — carga y resuelve datos de locale. Crea cada formateador una vez y reutilízalo, especialmente dentro de bucles o en el renderizado de listas. Construir un nuevo new Intl.NumberFormat(...) para cada fila puede ser mucho más lento que el formateo en sí.

// Slow: a new formatter is built on every iteration
prices.forEach((p) =>
  console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(p))
);

// Fast: build it once, reuse it
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
prices.forEach((p) => console.log(money.format(p)));
Información

Cada formateador también expone .resolvedOptions(), que informa el locale y las opciones realmente elegidas tras la negociación. Es útil para depurar casos en los que el entorno de ejecución recurre a un locale distinto al que solicitaste.

Resumen

La API Intl cubre las tareas de formateo y comparación que antes requerían pesadas librerías de terceros: números, monedas, fechas, tiempos relativos, plurales y listas sensibles al locale, además de la ordenación correcta de texto mediante Intl.Collator. Dado que está integrada en todos los navegadores modernos y en Node.js, recurrir a ella primero mantiene tu bundle pequeño y tu salida correcta para usuarios de todo el mundo. Recuerda la única regla que más beneficios aporta: crea cada formateador una vez y reutilízalo.

Pon a Prueba tus Conocimientos

Práctica
¿Qué constructor Intl formatea un número como moneda, y cómo?
¿Qué constructor Intl formatea un número como moneda, y cómo?
Práctica
¿Por qué [...words].sort() podría colocar letras acentuadas o mayúsculas en el orden incorrecto, y qué lo soluciona?
¿Por qué [...words].sort() podría colocar letras acentuadas o mayúsculas en el orden incorrecto, y qué lo soluciona?
Práctica
¿Cuál es la forma recomendada de usar un formateador Intl dentro de un bucle?
¿Cuál es la forma recomendada de usar un formateador Intl dentro de un bucle?
Was this page helpful?