How do you check what locale and options a formatter is actually using?

Use the resolvedOptions() method to inspect the actual configuration of any Intl formatter

Introduction

When you create an Intl formatter in JavaScript, the options you request are not always the options you get. The browser performs locale negotiation, fills in default values, and normalizes your settings to create the final configuration. The resolvedOptions() method lets you inspect exactly what the formatter is actually using.

Every formatter in the Intl API has a resolvedOptions() method. This includes Intl.DateTimeFormat, Intl.NumberFormat, Intl.ListFormat, Intl.PluralRules, Intl.Collator, and others. The method returns an object containing all the configuration details that the formatter ended up with after processing your input.

This method is primarily useful for debugging, understanding browser behavior, and detecting which features are available in the current environment.

The basic syntax

The resolvedOptions() method takes no parameters. You call it on any formatter instance and it returns an object.

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',
//   ...
// }

The returned object always includes at minimum the locale, calendar, and numberingSystem properties for date formatters, or locale and numberingSystem for number formatters. Additional properties depend on what options you specified and what the formatter type supports.

Why requested options differ from resolved options

There are three main reasons why the options you requested might differ from the resolved options.

First, locale negotiation finds the best available locale when your exact request is not supported. If you request de-AT but the browser only has de, the resolved locale will be de.

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

console.log(options.locale);
// Likely outputs: 'de-AT' or 'de'

console.log(options.calendar);
// Likely outputs: 'gregory' (if Buddhist calendar is not supported)

Second, the browser fills in default values for any options you do not specify. These defaults are locale-specific.

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

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

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

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

Third, the browser normalizes certain options into their canonical form. If you use dateStyle or timeStyle, the browser does not include these in the resolved options. Instead, it includes the individual component options that they expand to.

Checking the actual locale being used

The locale property in resolved options tells you exactly which locale the formatter is using. This is the result of locale negotiation.

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

console.log(options.locale);
// Outputs the first supported locale from the list

If you request a locale that includes Unicode extension keywords, the resolved locale might not include those keywords if they were not supported or were applied as separate options.

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

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

console.log(options.numberingSystem);
// Might output: 'arab' or 'latn' depending on support

Inspecting date and time formatting options

For Intl.DateTimeFormat, the resolved options include details about which date and time components will be displayed and how.

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);
// Outputs: 'numeric'

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

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

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

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

When you use dateStyle or timeStyle, those shortcuts are not included in the resolved options. The browser expands them into individual component options based on the locale.

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

const options = formatter.resolvedOptions();

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

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

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

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

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

If you create a date formatter with no options at all, the resolved options show you what the browser chose as defaults for that locale.

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

console.log(options);
// Shows default date component options for Japanese locale

Inspecting number formatting options

For Intl.NumberFormat, the resolved options tell you the style, precision, grouping, and other formatting details.

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

const options = formatter.resolvedOptions();

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

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

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

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

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

You can see that even though you only specified the currency, the browser filled in default values for currencyDisplay and the fraction digits.

When you use rounding options, the resolved options show you exactly how numbers will be rounded.

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

const options = formatter.resolvedOptions();

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

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

Inspecting other formatter types

The resolvedOptions() method works the same way on all Intl formatters.

For Intl.ListFormat, it shows you the type and style.

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

const options = formatter.resolvedOptions();

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

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

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

For Intl.PluralRules, it shows you the type and minimum/maximum digits.

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

const options = formatter.resolvedOptions();

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

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

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

Common use cases for resolvedOptions()

The most common use case is debugging. When formatted output does not look the way you expect, resolvedOptions() helps you understand what the formatter is actually doing.

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

console.log(formatter.format(new Date()));
// Check the output

console.log(formatter.resolvedOptions());
// See exactly which options produced that output

Another use case is feature detection. You can check whether a specific calendar, numbering system, or other feature is supported by requesting it and seeing what was actually resolved.

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

const options = formatter.resolvedOptions();

if (options.calendar === 'islamic') {
  console.log('Islamic calendar is supported');
} else {
  console.log('Islamic calendar is not supported, using ' + options.calendar);
}

You can also use resolvedOptions() to get the user's locale preferences. When you create a formatter with no locale argument, the browser uses the user's preferences.

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

console.log(options.locale);
// Outputs: the user's preferred locale

console.log(options.timeZone);
// Outputs: the user's time zone

console.log(options.hourCycle);
// Outputs: the user's hour cycle preference (12 or 24 hour)

Finally, you can use the resolved options to recreate an identical formatter. The returned object can be passed back to the 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 will format numbers identically to formatter1

Key takeaways

The resolvedOptions() method returns an object containing the actual configuration that a formatter is using. This configuration might differ from what you requested due to locale negotiation, default values, and normalization.

Every Intl formatter has this method. You call it with no parameters and receive an object with properties like locale, calendar, numberingSystem, and formatter-specific options.

Use resolvedOptions() primarily for debugging formatter behavior, detecting available features, and understanding how the browser interpreted your options. The returned object can also be used to recreate an identical formatter or inspect user preferences.