Stage 1 Draft / March 10, 2026

Amount

Introduction

This specification consists of two parts:

Editor's Note

The changes proposed here are stacked on top of the Keep Trailing Zeros ECMA-402 proposal, and include calls to ECMA-402 Abstract Operations from ECMA​-262 algorithms. Where necessary, we intend to promote those semantics to ECMA​-262.

1 The Amount Object

Introduction

An Amount is an object that wraps a numeric value—as a Number, BigInt, or String—together with an optional unit (e.g., mile, kilogram, EUR, JPY, USD-per-mile). One can intuitively understand an Amount as a value that, so to speak, knows what it is measuring.

When precision options (such as fractionDigits or significantDigits) are applied, or when unit conversion is performed, the numeric value is stored as a decimal digit string, which is a String in StrDecimalLiteral form or "NaN". Otherwise, the original JavaScript value type (Number, BigInt, or String) is retained.

Rounding a mathematical value is an important part of this spec. When we say rounding mode in this specification we simply refer to ECMA-402's definition.

1.1 Abstract Operations

1.1.1 GetOption ( options, property, type, values, default )

The abstract operation GetOption takes arguments options (an Object), property (a property key), type (boolean, string or number), values (empty or a List of ECMAScript language values), and default (required or an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It extracts the value of the specified property of options, converts it to the required type, checks whether it is allowed by values if values is not empty, and substitutes default if the value is undefined. It performs the following steps when called:

  1. Let value be ? Get(options, property).
  2. If value is undefined, then
    1. If default is required, throw a RangeError exception.
    2. Return default.
  3. If type is boolean, then
    1. Set value to ToBoolean(value).
  4. Else if type is number, then
    1. Set value to ? ToNumber(value).
  5. Else,
    1. Assert: type is string.
    2. Set value to ? ToString(value).
  6. If values is not empty and values does not contain value, throw a RangeError exception.
  7. Return value.

1.1.2 GetAmountOptions ( opts )

The abstract operation GetAmountOptions takes argument opts (an Object) and returns either a normal completion containing a Record with fields [[FractionDigits]] (a non-negative integer or undefined), [[RoundingMode]] (a rounding mode), [[SignificantDigits]] (a positive integer or undefined), and [[Unit]] (a String or undefined) or a throw completion. It validates the given options (an ECMAScript object) for creating an Amount and returns a Record with slots set to appropriate marthematical values (or undefined). It performs the following steps when called:

  1. Let opts be ? GetOptionsObject(opts).
  2. Let fractionDigits be ? GetOption(opts, "fractionDigits", number, empty, undefined).
  3. Let roundingMode be ? GetOption(opts, "roundingMode", string, « "ceil", "floor", "expand", "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven" », "halfEven").
  4. Let significantDigits be ? GetOption(opts, "significantDigits", number, empty, undefined).
  5. Let unit be ? GetOption(opts, "unit", string, empty, undefined).
  6. If fractionDigits is not undefined, then
    1. If significantDigits is not undefined, throw a RangeError exception.
    2. If fractionDigits is not an integral Number, throw a RangeError exception.
  7. Else if significantDigits is not undefined, then
    1. If significantDigits is not an integral Number, throw a RangeError exception.
    2. If significantDigits < 1𝔽, throw a RangeError exception.
  8. If unit is the empty String, throw a RangeError exception.
  9. Return the Record { [[FractionDigits]]: fractionDigits, [[RoundingMode]]: roundingMode, [[SignificantDigits]]: significantDigits, [[Unit]]: unit }.

1.1.3 GetAmountConvertToOptions ( opts )

The abstract operation GetAmountConvertToOptions takes argument opts (an Object) and returns either a normal completion containing a Record with fields [[MinFractionDigits]] (a non-negative integer or undefined), [[MaxFractionDigits]] (a non-negative integer or undefined), [[RoundingMode]] (a rounding mode), [[RoundingPriority]] (a String), [[MinSignificantDigits]] (a positive integer or undefined), [[MaxSignificantDigits]] (a positive integer or undefined), [[Locale]] (a String or undefined), [[Usage]] (a String or undefined), and [[Unit]] (a String or undefined) or a throw completion. It validates the given options (an ECMAScript object) for converting an Amount to another Amount and returns a Record with slots set to appropriate marthematical values (or undefined). It performs the following steps when called:

  1. Let opts be ? GetOptionsObject(opts).
  2. Let minFractionDigits be ? GetOption(opts, "minimumfractionDigits", number, empty, undefined).
  3. Let maxFractionDigits be ? GetOption(opts, "maximumfractionDigits", number, empty, undefined).
  4. Let roundingMode be ? GetOption(opts, "roundingMode", string, « "ceil", "floor", "expand", "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven" », "halfEven").
  5. Let roundingPriority be ? GetOption(opts, "roundingPriority", string, empty, undefined).
  6. Let minSignificantDigits be ? GetOption(opts, "minimumSignificantDigits", number, empty, undefined).
  7. Let maxSignificantDigits be ? GetOption(opts, "maximumSignificantDigits", number, empty, undefined).
  8. Let significantDigits be ? GetOption(opts, "maximumSignificantDigits", number, empty, undefined).
  9. Let unit be ? GetOption(opts, "unit", string, empty, undefined).
  10. If minFractionDigits is not undefined and not an integral Number, throw a RangeError exception.
  11. If maxFractionDigits is not undefined and not an integral Number, throw a RangeError exception.
  12. If minSignificantDigits is not undefined and not an integral Number, throw a RangeError exception.
  13. If maxSignificantDigits is not undefined and not an integral Number, throw a RangeError exception.
  14. If unit is the empty String, throw a RangeError exception.
  15. Return the Record { [[MinimumFractionDigits]]: minFractionDigits, [[MaximumFractionDigits]]: maxFractionDigits, [[MinimumSignificantDigits]]: minSignificantDigits, [[MaximumSignificantDigits]]: maxSignificantDigits, [[RoundingMode]]: roundingMode, [[RoundingPriority]]: roundingPriority, [[SignificantDigits]]: significantDigits, [[Unit]]: unit }.
Editor's Note

This abstract operation will need to be overridden in the 402 part because it will read additional Intl-specific properties beyond these.

1.1.4 GetUnitConversionFactor ( unit )

The implementation-defined abstract operation GetUnitConversionFactor takes argument unit (a String) and returns either a normal completion containing a Record with fields [[Category]] (a String), [[Factor]] (a Number), and [[Offset]] (a Number) or a throw completion. It returns the conversion data for converting unit to its base unit within its unit category. It performs the following steps when called:

  1. If unit does not have a corresponding <convertUnit> element in UTS #35 Part 6 Supplemental, Unit Conversion, or if that element specifies a special conversion, throw a RangeError exception.
  2. Let category be the unit category of unit as specified by the CLDR unit conversion data.
  3. Let factor be the Number value closest to the rational conversion factor for unit as specified by the CLDR unit conversion data.
  4. If the CLDR unit conversion data specifies a conversion offset for unit, let offset be the Number value closest to that rational offset; otherwise, let offset be +0𝔽.
  5. Return the Record { [[Category]]: category, [[Factor]]: factor, [[Offset]]: offset }.
Note

The formula for converting a value in unit to its base unit is: baseValue = value × [[Factor]] + [[Offset]].

CLDR expresses conversion factors as rational numbers (e.g., 0.3048/12 for inch-to-meter). These rational values are converted to Numbers before use, so conversion arithmetic is subject to the precision of IEEE 754 binary64. For example, converting 1.75 feet to inches yields 1.75 × 0.3048 / (0.3048 / 12) = 20.999999999999996, not exactly 21.

CLDR also defines nonlinear conversions via the special attribute (e.g., the Beaufort scale). These cannot be expressed as a linear factor and offset, so they are excluded from this operation.

1.1.5 ConvertUnitValue ( value, sourceUnit, targetUnit )

The abstract operation ConvertUnitValue takes arguments value (a Number), sourceUnit (a String), and targetUnit (a String) and returns either a normal completion containing a Number or a throw completion. It converts value from sourceUnit to targetUnit using Number arithmetic. It performs the following steps when called:

  1. Let sourceConv be ? GetUnitConversionFactor(sourceUnit).
  2. Let targetConv be ? GetUnitConversionFactor(targetUnit).
  3. If SameValue(sourceConv.[[Category]], targetConv.[[Category]]) is false, throw a RangeError exception.
  4. Let sourceFactor be sourceConv.[[Factor]].
  5. Let sourceOffset be sourceConv.[[Offset]].
  6. Let targetFactor be targetConv.[[Factor]].
  7. Let targetOffset be targetConv.[[Offset]].
  8. Let baseValue be value × sourceFactor + sourceOffset.
  9. Let result be (baseValue - targetOffset) / targetFactor.
  10. Return result.

1.2 The Amount Constructor

The Amount constructor:

  • is %Amount%.
  • is the initial value of the the "Amount" property of the global object.
  • creates and initializes a new Amount object when called as a constructor
  • may be used as the value of an extends clause of a class definition.

1.2.1 Amount ( x [ , opts ] )

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If x is not a Number, not a BigInt, and not a String, throw a TypeError exception.
  3. If x is a String, then
    1. Let text be StringToCodePoints(x).
    2. Let parsed be ParseText(text, StringNumericLiteral).
    3. If parsed is a List of errors, throw a RangeError exception.
  4. Let validatedOpts be ? GetAmountOptions(opts).
  5. Let roundingMode be validatedOpts.[[RoundingMode]].
  6. Let fractionDigits be validatedOpts.[[FractionDigits]].
  7. Let significantDigits be validatedOpts.[[SignificantDigits]].
  8. Let unit be validatedOpts.[[Unit]].
  9. If x is a Number or x is a BigInt, then
    1. Let value be x.
  10. Else,
    1. Assert: x is a String.
    2. TODO Let intlObject be an Object suitable as a first argument FormatNumericToString, using fractionDigits, significantDigits, and roundingMode.
    3. Let intlMV be ! ToIntlMathematicalValue(x).
    4. Let formatted be FormatNumericToString(intlObject, intlMV.[[Value]], intlMV.[[StringDigitCount]]).
    5. Let value be formatted.[[FormattedString]].
  11. Let O be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
  12. Set O.[[AmountValue]] to value.
  13. Set O.[[Unit]] to unit.
  14. Return O.
Note

When no precision options are given, Number and BigInt arguments are stored directly in [[AmountValue]], preserving the original type. String arguments are normalized to StrDecimalLiteral form. When precision options are specified, [[AmountValue]] always holds a String.

Editor's Note

We intend to move 402's FormatNumericToString, and its dependent AOs, to 262, possibly renamed.

2 Properties of the Amount Prototype

2.1 get Amount.prototype.value

This accessor property, whose set accessor function is undefined, returns the numeric value of the Amount. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Return O.[[AmountValue]].
Note

The value may be a Number, BigInt, or String. It is a String when precision options were applied during construction or when the Amount is the result of unit conversion.

2.2 get Amount.prototype.unit

This accessor property, whose set accessor function is undefined, returns a String value (or undefined) indicating the unit that this Amount has. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Return O.[[Unit]].

2.3 Amount.prototype.toString ( )

This method returns a String representation of the Amount, including a unit indicator in bracket notation.

It performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Let v be O.[[AmountValue]].
  4. Let u be O.[[Unit]].
  5. If v is a String, then
    1. Let valueStr be v.
  6. Else if v is a Number, then
    1. Let valueStr be Number::toString(v, 10).
  7. Else,
    1. Assert: v is a BigInt.
    2. Let valueStr be BigInt::toString(v, 10).
  8. If u is undefined, return the string-concatenation of valueStr and "[]".
  9. Return the string-concatenation of valueStr, "[", u, and "]".

2.4 Amount.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

It performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Return ? Call(%Amount.prototype.toString%, O, « »).

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

2.5 Amount.prototype.convertTo ( options )

This method returns a new Amount whose value is the result of converting this Amount’s value from its current unit to a target unit. The target unit is specified by options.

It performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Let sourceUnit be O.[[Unit]].
  4. If sourceUnit is undefined, throw a TypeError exception.
  5. Let validatedOpts be ? GetAmountConvertToOptions(options).
  6. Let targetUnit be validatedOpts.[[Unit]].
  7. If targetUnit is undefined, throw a TypeError exception.
  8. Let roundingMode be validatedOpts.[[RoundingMode]].
  9. Let roundingPriority be validatedOpts.[[RoundingPriority]].
  10. Let minFractionDigits be validatedOpts.[[MinimumFractionDigits]].
  11. Let maxFractionDigits be validatedOpts.[[MaximumFractionDigits]].
  12. Let minSignificantDigits be validatedOpts.[[MinimumSignificantDigits]].
  13. Let maxSignificantDigits be validatedOpts.[[MaximumSignificantDigits]].
  14. Let v be O.[[AmountValue]].
  15. If v is a Number, then
    1. Let sourceValue be v.
  16. Else if v is a BigInt, then
    1. Let sourceValue be 𝔽((v)).
  17. Else,
    1. Assert: v is a String.
    2. Let sourceValue be StringToNumber(v).
  18. Let convertedValue be ? ConvertUnitValue(sourceValue, sourceUnit, targetUnit).
  19. TODO Let intlObject be an Object suitable as the first argument of FormatNumericToString, using minFractionDigits, maxFractionDigits, minSignificantDigits, maxSignificantDigits, roundingPriority, and roundingMode.
  20. Let formatted be FormatNumericToString(intlObject, convertedValue, 0).
  21. Let result be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
  22. Set result.[[AmountValue]] to formatted.[[FormattedString]].
  23. Set result.[[Unit]] to targetUnit.
  24. Return result.
Note

An ECMAScript implementation that includes the ECMA-402 Internationalization API supersedes this method to additionally support locale-based and usage-based unit conversion via CLDR unit preferences data. Without ECMA-402, only explicit unit-to-unit conversion (via the "unit" option) is supported.

3 Amendments to the ECMAScript® 2024 Internationalization API Specification

Editor's Note

This section lists amendments which must be made to ECMA-402, the ECMAScript® 2024 Internationalization API Specification. Text to be added is marked like this, and text to be deleted is marked like this. Blocks of unmodified text between modified sections are marked by [...].

3.1 Properties of the Amount Prototype Object

3.1.1 Amount.prototype.toLocaleString ( [ locales [ , options ] ] )

This definition supersedes the definition provided in es2025, 2.4.

This function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Let v be O.[[AmountValue]].
  4. If v is a String, then
    1. Let numValue be v.
  5. Else if v is a BigInt, then
    1. Let numValue be BigInt::toString(v, 10).
  6. Else,
    1. Assert: v is a Number.
    2. Let numValue be v.
  7. Let unit be O.[[Unit]].
  8. Let mergedOptions be OrdinaryObjectCreate(null).
  9. If options is not undefined, then
    1. Let optionsObj be ? GetOptionsObject(options).
    2. Perform ? CopyDataProperties(mergedOptions, optionsObj, « »).
  10. If unit is not undefined, then
    1. If ? HasProperty(mergedOptions, "style") is false, then
      1. If IsWellFormedCurrencyCode(unit) is true, then
        1. Perform ! CreateDataPropertyOrThrow(mergedOptions, "style", "currency").
        2. If ? HasProperty(mergedOptions, "currency") is false, then
          1. Perform ! CreateDataPropertyOrThrow(mergedOptions, "currency", unit).
      2. Else,
        1. Perform ! CreateDataPropertyOrThrow(mergedOptions, "style", "unit").
        2. If ? HasProperty(mergedOptions, "unit") is false, then
          1. Perform ! CreateDataPropertyOrThrow(mergedOptions, "unit", unit).
  11. Let numberFormat be ? Construct(%Intl.NumberFormat%, « locales, mergedOptions »).
  12. Return FormatNumeric(numberFormat, numValue).

3.1.2 Amount.prototype.convertTo ( options )

This definition supersedes the definition provided in es2025, 2.5.

This function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[AmountValue]]).
  3. Let sourceUnit be O.[[Unit]].
  4. If sourceUnit is undefined, throw a TypeError exception.
  5. Let validatedOpts be ? GetAmountConvertToOptions(options).
  6. Let targetUnit be validatedOpts.[[Unit]].
  7. Let roundingMode be validatedOpts.[[RoundingMode]].
  8. Let roundingPriority be validatedOpts.[[RoundingPriority]].
  9. Let minFractionDigits be validatedOpts.[[MiniumumFractionDigits]].
  10. Let maxFractionDigits be validatedOpts.[[MaximumFractionDigits]].
  11. Let minSignificantDigits be validatedOpts.[[MinimumSignificantDigits]].
  12. Let maxSignificantDigits be validatedOpts.[[MaximumSignificantDigits]].
  13. Let locale be validatedOpts.[[Locale]].
  14. Let usage be validatedOpts.[[Usage]].
  15. If targetUnit is undefined and locale is undefined and usage is undefined, throw a TypeError exception.
  16. Let v be O.[[AmountValue]].
  17. If v is a Number, then
    1. Let sourceValue be v.
  18. Else if v is a BigInt, then
    1. Let sourceValue be 𝔽((v)).
  19. Else,
    1. Assert: v is a String.
    2. Let sourceValue be StringToNumber(v).
  20. If targetUnit is not undefined, then
    1. If locale is not undefined or usage is not undefined, throw a TypeError exception.
  21. Else,
    1. Let matcher be ? GetOption(validatedOpts, "localeMatcher", string, « "lookup", "best fit" », "best fit").
    2. Let requestedLocales be ? CanonicalizeLocaleList(locale).
    3. If usage is undefined, set usage to "default".
    4. Set targetUnit to ? ResolveUnitPreference(sourceUnit, sourceValue, requestedLocales, usage, matcher).
  22. Let convertedValue be ? ConvertUnitValue(sourceValue, sourceUnit, targetUnit).
  23. Let result be OrdinaryObjectCreate(%Amount.prototype%, « [[AmountValue]], [[Unit]] »).
  24. TODO Let intlObject be an Object suitable for use as the first argument of a call to FormatNumericToString that uses minSignificantDigits, maxSignificantDigits, minFractionDigits, maxFractionDigits, roundingPriority, and roundingMode.
  25. Let formatted be FormatNumericToString(intlObject, convertedValue, 0).
  26. Set result.[[AmountValue]] to formatted.[[FormattedString]].
  27. Set result.[[Unit]] to targetUnit.
  28. Return result.

3.1.3 ResolveUnitPreference ( sourceUnit, sourceValue, requestedLocales, usage, localeMatcher )

The implementation-defined abstract operation ResolveUnitPreference takes arguments sourceUnit (a String), sourceValue (a Number), requestedLocales (a Language Priority List), usage (a String), and localeMatcher (a String) and returns either a normal completion containing a String or a throw completion. It determines the preferred target unit for sourceUnit in the locale best matching requestedLocales and usage context, based on CLDR unit preferences data. It performs the following steps when called:

  1. Let sourceConv be ? GetUnitConversionFactor(sourceUnit).
  2. Let category be sourceConv.[[Category]].
  3. Let availableLocales be the Available Locales List for locales for which the <unitPreferences> element data of UTS #35 Part 6 Supplemental, Unit Preferences includes data.
  4. Let localeData be a Record whose field names are the elements of availableLocales and whose values are Records.
  5. Let r be ResolveLocale(availableLocales, requestedLocales, the Record { [[localeMatcher]]: localeMatcher }, « », localeData).
  6. Let locale be r.[[Locale]].
  7. Let preferredUnit be the preferred unit for category, locale, usage, and sourceValue as specified by the <unitPreferences> element data of UTS #35 Part 6 Supplemental, Unit Preferences.
  8. If preferredUnit is undefined, throw a RangeError exception.
  9. Return preferredUnit.

3.2 Amendment to the Normative References of ECMA-402

Editor's Note

The following entry is to be added to ECMA-402's list of referenced parts of Unicode Technical Standard #35.

4 NumberFormat Objects

4.1 Abstract Operations for NumberFormat Objects

4.1.1 GetNumberFormatPattern ( numberFormat, x )

The abstract operation GetNumberFormatPattern takes arguments numberFormat (an Intl.NumberFormat) and x (an Intl mathematical value) and returns either a normal completion containing a String or a throw completion. It considers the resolved unit-related options in the number format object along with the final scaled and rounded number being formatted (an Intl mathematical value) and returns a pattern, a String value as described in 16.2.3. It performs the following steps when called:

  1. Let resolvedLocaleData be numberFormat.[[LocaleData]].
  2. Let patterns be resolvedLocaleData.[[patterns]].
  3. Assert: patterns is a Record (see 16.2.3).
  4. Let style be numberFormat.[[Style]].
  5. If style is "percent", then
    1. Set patterns to patterns.[[percent]].
  6. Else if style is "unit", then
    1. Let unit be numberFormat.[[Unit]].
    2. Let fmtUnit be x.[[Unit]].
    3. If fmtUnit is not undefined and SameValueNonNumber(unit, fmtUnit) is false, then
      1. If unit is not undefined, throw a TypeError exception.
      2. Set unit to fmtUnit.
    4. Else if unit is undefined, then
      1. Throw a TypeError exception.
    5. Let unitDisplay be numberFormat.[[UnitDisplay]].
    6. Set patterns to patterns.[[unit]].
    7. If patterns doesn't have a field [[<unit>]], then
      1. Set unit to "fallback".
    8. Set patterns to patterns.[[<unit>]].
    9. Set patterns to patterns.[[<unitDisplay>]].
  7. Else if style is "currency", then
    1. Let currency be numberFormat.[[Currency]].
    2. Let fmtCurrency be x.[[Currency]].
    3. If fmtCurrency is not undefined and SameValueNonNumber(currency, fmtCurrency) is false, then
      1. If currency is not undefined, throw a TypeError exception.
      2. Set currency to fmtCurrency.
    4. Else if currency is undefined, then
      1. Throw a TypeError exception.
    5. Let currencyDisplay be numberFormat.[[CurrencyDisplay]].
    6. Let currencySign be numberFormat.[[CurrencySign]].
    7. Set patterns to patterns.[[currency]].
    8. If patterns doesn't have a field [[<currency>]], then
      1. Set currency to "fallback".
    9. Set patterns to patterns.[[<currency>]].
    10. Set patterns to patterns.[[<currencyDisplay>]].
    11. Set patterns to patterns.[[<currencySign>]].
  8. Else,
    1. Assert: style is "decimal".
    2. Set patterns to patterns.[[decimal]].
  9. If x is negative-infinity, then
    1. Let category be negative-non-zero.
  10. Else if x is negative-zero, then
    1. Let category be negative-zero.
  11. Else if x is not-a-number, then
    1. Let category be positive-zero.
  12. Else if x is positive-infinity, then
    1. Let category be positive-non-zero.
  13. Else,
    1. Assert: x is a mathematical value.
    2. If x < 0, then
      1. Let category be negative-non-zero.
    3. Else if x > 0, then
      1. Let category be positive-non-zero.
    4. Else,
      1. Let category be positive-zero.
  14. Let signDisplay be numberFormat.[[SignDisplay]].
  15. If signDisplay is "never", then
    1. Let pattern be patterns.[[zeroPattern]].
  16. Else if signDisplay is "auto", then
    1. If category is positive-non-zero or positive-zero, then
      1. Let pattern be patterns.[[zeroPattern]].
    2. Else,
      1. Let pattern be patterns.[[negativePattern]].
  17. Else if signDisplay is "always", then
    1. If category is positive-non-zero or positive-zero, then
      1. Let pattern be patterns.[[positivePattern]].
    2. Else,
      1. Let pattern be patterns.[[negativePattern]].
  18. Else if signDisplay is "exceptZero", then
    1. If category is positive-zero or negative-zero, then
      1. Let pattern be patterns.[[zeroPattern]].
    2. Else if category is positive-non-zero, then
      1. Let pattern be patterns.[[positivePattern]].
    3. Else,
      1. Let pattern be patterns.[[negativePattern]].
  19. Else,
    1. Assert: signDisplay is "negative".
    2. If category is negative-non-zero, then
      1. Let pattern be patterns.[[negativePattern]].
    3. Else,
      1. Let pattern be patterns.[[zeroPattern]].
  20. Return pattern.

4.1.2 SetNumberFormatUnitOptions ( intlObj, options )

The abstract operation SetNumberFormatUnitOptions takes arguments intlObj (an Intl.NumberFormat) and options (an Object) and returns either a normal completion containing unused or a throw completion. It resolves the user-specified options relating to units onto intlObj. It performs the following steps when called:

  1. Let style be ? GetOption(options, "style", string, « "decimal", "percent", "currency", "unit" », "decimal").
  2. Set intlObj.[[Style]] to style.
  3. Let currency be ? GetOption(options, "currency", string, empty, undefined).
  4. If currency is undefined, then
    1. If style is "currency", throw a TypeError exception.
  5. Else,
    1. If IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
  6. If currency is not undefined and IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
  7. Let currencyDisplay be ? GetOption(options, "currencyDisplay", string, « "code", "symbol", "narrowSymbol", "name" », "symbol").
  8. Let currencySign be ? GetOption(options, "currencySign", string, « "standard", "accounting" », "standard").
  9. Let unit be ? GetOption(options, "unit", string, empty, undefined).
  10. If unit is undefined, then
    1. If style is "unit", throw a TypeError exception.
  11. Else,
    1. If IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
  12. If unit is not undefined and IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
  13. Let unitDisplay be ? GetOption(options, "unitDisplay", string, « "short", "narrow", "long" », "short").
  14. If style is "currency", then
    1. If currency is not undefined, set Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
    2. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.
    3. Set intlObj.[[CurrencySign]] to currencySign.
  15. If style is "unit", then
    1. If unit is not undefined, Set set intlObj.[[Unit]] to unit.
    2. Set intlObj.[[UnitDisplay]] to unitDisplay.
  16. Return unused.

5 Normative References

Copyright & Software License

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.