¿Cómo comprobar qué configuración regional y opciones está utilizando realmente un formateador?

Utiliza el método resolvedOptions() para inspeccionar la configuración real de cualquier formateador Intl

Introducción

Cuando creas un formateador Intl en JavaScript, las opciones que solicitas no siempre son las opciones que obtienes. El navegador realiza una negociación de configuración regional, completa los valores predeterminados y normaliza tu configuración para crear la configuración final. El método resolvedOptions() te permite inspeccionar exactamente lo que el formateador está utilizando realmente.

Cada formateador en la API Intl tiene un método resolvedOptions(). Esto incluye Intl.DateTimeFormat, Intl.NumberFormat, Intl.ListFormat, Intl.PluralRules, Intl.Collator, y otros. El método devuelve un objeto que contiene todos los detalles de configuración con los que el formateador terminó después de procesar tu entrada.

Este método es principalmente útil para depurar, entender el comportamiento del navegador y detectar qué características están disponibles en el entorno actual.

La sintaxis básica

El método resolvedOptions() no toma parámetros. Lo llamas en cualquier instancia de formateador y devuelve un objeto.

const formatter = new Intl.DateTimeFormat('en-US');
const options = formatter.resolvedOptions();

console.log(options);
// {
//   locale: 'en-US',
//   calendar: 'gregory',
//   numberingSystem: 'latn',
//   timeZone: 'America/Los_Angeles',
//   ...
// }

El objeto devuelto siempre incluye como mínimo las propiedades locale, calendar y numberingSystem para formateadores de fecha, o locale y numberingSystem para formateadores de números. Las propiedades adicionales dependen de qué opciones especificaste y qué tipo de formateador soporta.

Por qué las opciones solicitadas difieren de las opciones resueltas

Hay tres razones principales por las que las opciones que solicitaste podrían diferir de las opciones resueltas.

Primero, la negociación de configuración regional encuentra la mejor configuración disponible cuando tu solicitud exacta no es compatible. Si solicitas de-AT pero el navegador solo tiene de, la configuración regional resuelta será de.

const formatter = new Intl.DateTimeFormat('de-AT-u-ca-buddhist');
const options = formatter.resolvedOptions();

console.log(options.locale);
// Probablemente muestra: 'de-AT' o 'de'

console.log(options.calendar);
// Probablemente muestra: 'gregory' (si el calendario budista no es compatible)

Segundo, el navegador completa con valores predeterminados cualquier opción que no especifiques. Estos valores predeterminados son específicos de la configuración regional.

const formatter = new Intl.NumberFormat('en-US');
const options = formatter.resolvedOptions();

console.log(options.style);
// Muestra: 'decimal'

console.log(options.minimumFractionDigits);
// Muestra: 0

console.log(options.maximumFractionDigits);
// Muestra: 3

Tercero, el navegador normaliza ciertas opciones a su forma canónica. Si utilizas dateStyle o timeStyle, el navegador no incluye estos en las opciones resueltas. En su lugar, incluye las opciones de componentes individuales a las que se expanden.

Comprobando el locale que se está utilizando

La propiedad locale en las opciones resueltas te indica exactamente qué locale está utilizando el formateador. Este es el resultado de la negociación de locale.

const formatter = new Intl.DateTimeFormat(['zh-TW', 'zh-CN', 'en-US']);
const options = formatter.resolvedOptions();

console.log(options.locale);
// Muestra el primer locale compatible de la lista

Si solicitas un locale que incluye palabras clave de extensión Unicode, el locale resuelto podría no incluir esas palabras clave si no eran compatibles o se aplicaron como opciones separadas.

const formatter = new Intl.NumberFormat('en-US-u-nu-arab');
const options = formatter.resolvedOptions();

console.log(options.locale);
// Podría mostrar: 'en-US'

console.log(options.numberingSystem);
// Podría mostrar: 'arab' o 'latn' dependiendo del soporte

Inspeccionando opciones de formato de fecha y hora

Para Intl.DateTimeFormat, las opciones resueltas incluyen detalles sobre qué componentes de fecha y hora se mostrarán y cómo.

const formatter = new Intl.DateTimeFormat('en-US', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  timeZone: 'America/New_York'
});

const options = formatter.resolvedOptions();

console.log(options.year);
// Muestra: 'numeric'

console.log(options.month);
// Muestra: 'long'

console.log(options.day);
// Muestra: 'numeric'

console.log(options.timeZone);
// Muestra: 'America/New_York'

console.log(options.calendar);
// Muestra: 'gregory'

Cuando utilizas dateStyle o timeStyle, esos atajos no se incluyen en las opciones resueltas. El navegador los expande en opciones de componentes individuales basadas en el locale.

const formatter = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'full'
});

const options = formatter.resolvedOptions();

console.log(options.dateStyle);
// Muestra: undefined

console.log(options.weekday);
// Muestra: 'long'

console.log(options.year);
// Muestra: 'numeric'

console.log(options.month);
// Muestra: 'long'

console.log(options.day);
// Muestra: 'numeric'

Si creas un formateador de fecha sin ninguna opción, las opciones resueltas te muestran lo que el navegador eligió como valores predeterminados para ese locale.

const formatter = new Intl.DateTimeFormat('ja-JP');
const options = formatter.resolvedOptions();

console.log(options);
// Muestra las opciones de componentes de fecha predeterminadas para el locale japonés

Inspección de opciones de formato de números

Para Intl.NumberFormat, las opciones resueltas te indican el estilo, precisión, agrupación y otros detalles de formato.

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

const options = formatter.resolvedOptions();

console.log(options.style);
// Salida: 'currency'

console.log(options.currency);
// Salida: 'USD'

console.log(options.currencyDisplay);
// Salida: 'symbol'

console.log(options.minimumFractionDigits);
// Salida: 2

console.log(options.maximumFractionDigits);
// Salida: 2

Puedes ver que aunque solo especificaste la moneda, el navegador completó valores predeterminados para currencyDisplay y los dígitos decimales.

Cuando utilizas opciones de redondeo, las opciones resueltas te muestran exactamente cómo se redondearán los números.

const formatter = new Intl.NumberFormat('en-US', {
  minimumSignificantDigits: 3,
  maximumSignificantDigits: 5
});

const options = formatter.resolvedOptions();

console.log(options.minimumSignificantDigits);
// Salida: 3

console.log(options.maximumSignificantDigits);
// Salida: 5

Inspección de otros tipos de formateadores

El método resolvedOptions() funciona de la misma manera en todos los formateadores Intl.

Para Intl.ListFormat, muestra el tipo y estilo.

const formatter = new Intl.ListFormat('en-US', {
  style: 'long',
  type: 'conjunction'
});

const options = formatter.resolvedOptions();

console.log(options.locale);
// Salida: 'en-US'

console.log(options.style);
// Salida: 'long'

console.log(options.type);
// Salida: 'conjunction'

Para Intl.PluralRules, muestra el tipo y los dígitos mínimos/máximos.

const formatter = new Intl.PluralRules('en-US', {
  type: 'ordinal'
});

const options = formatter.resolvedOptions();

console.log(options.locale);
// Salida: 'en-US'

console.log(options.type);
// Salida: 'ordinal'

console.log(options.minimumIntegerDigits);
// Salida: 1

Casos de uso comunes para resolvedOptions()

El caso de uso más común es la depuración. Cuando el resultado formateado no se ve como esperabas, resolvedOptions() te ayuda a entender qué está haciendo realmente el formateador.

const formatter = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'medium'
});

console.log(formatter.format(new Date()));
// Verifica la salida

console.log(formatter.resolvedOptions());
// Ve exactamente qué opciones produjeron esa salida

Otro caso de uso es la detección de características. Puedes verificar si un calendario específico, sistema de numeración u otra característica es compatible solicitándola y viendo qué se resolvió realmente.

const formatter = new Intl.DateTimeFormat('en-US', {
  calendar: 'islamic'
});

const options = formatter.resolvedOptions();

if (options.calendar === 'islamic') {
  console.log('El calendario islámico es compatible');
} else {
  console.log('El calendario islámico no es compatible, usando ' + options.calendar);
}

También puedes usar resolvedOptions() para obtener las preferencias de configuración regional del usuario. Cuando creas un formateador sin argumento de configuración regional, el navegador utiliza las preferencias del usuario.

const formatter = new Intl.DateTimeFormat();
const options = formatter.resolvedOptions();

console.log(options.locale);
// Salida: la configuración regional preferida del usuario

console.log(options.timeZone);
// Salida: la zona horaria del usuario

console.log(options.hourCycle);
// Salida: la preferencia de ciclo horario del usuario (12 o 24 horas)

Finalmente, puedes usar las opciones resueltas para recrear un formateador idéntico. El objeto devuelto puede pasarse de nuevo al constructor.

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

const options = formatter1.resolvedOptions();

const formatter2 = new Intl.NumberFormat(options.locale, options);

// formatter2 formateará números de manera idéntica a formatter1

Puntos clave

El método resolvedOptions() devuelve un objeto que contiene la configuración real que está utilizando un formateador. Esta configuración puede diferir de lo que solicitaste debido a la negociación de configuración regional, valores predeterminados y normalización.

Cada formateador Intl tiene este método. Lo llamas sin parámetros y recibes un objeto con propiedades como locale, calendar, numberingSystem y opciones específicas del formateador.

Utiliza resolvedOptions() principalmente para depurar el comportamiento del formateador, detectar características disponibles y comprender cómo interpretó el navegador tus opciones. El objeto devuelto también puede utilizarse para recrear un formateador idéntico o inspeccionar las preferencias del usuario.